Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data grid] updateRows triggers renderCell too many times #7821

Closed
2 tasks done
toyi opened this issue Feb 4, 2023 · 3 comments
Closed
2 tasks done

[data grid] updateRows triggers renderCell too many times #7821

toyi opened this issue Feb 4, 2023 · 3 comments
Labels
component: data grid This is the name of the generic UI component, not the React module! performance plan: Pro Impact at least one Pro user

Comments

@toyi
Copy link

toyi commented Feb 4, 2023

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

Link to live example: https://stackblitz.com/edit/react-ts-ocmxqz?file=App.tsx

Steps:

  1. Open and clear the console
  2. Click the "update" button on the top of the page

Current behavior 😯

Each click on "Update" triggers 8 times the same renderCell function.

In the project I'm working on, it's causing real performance issues (and for an unknown reason, it "only" renders each cell 4 times, not 8).

Expected behavior 🤔

Since the button click just calls grid.current.updateRows([{ id: 'abc' }]);, I would expect the render to occur 1 or 0 times, not 2+.

Context 🔦

I was having performance issues on what I would call a average+ complex table: 5 columns with 5 renderCells, many buttons that appear and disappear dependending on the user's actions.

There could be several causes of performance issues but rendering each cells 4 to 8 times surely doesn't help :p

I'm still in the process of learning React and MUI, so please don't be too harsh if I missed an issue or something in the doc. I saw several issues talking about performance problems, and renderCell often seems involved. I don't really know if they are related to my problem.

Aside to this issue, any advices on how to improve the performance when using renderCells would be greatly appreciated.

Your environment 🌎

npx @mui/envinfo
   System:
    OS: Linux 5.15 Ubuntu 22.04.1 LTS 22.04.1 LTS (Jammy Jellyfish)
  Binaries:
    Node: 16.19.0 - /usr/local/bin/node
    Yarn: 3.3.1 - /usr/local/bin/yarn
    npm: 8.19.3 - /usr/local/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    @emotion/react: ^11.10.5 => 11.10.5
    @emotion/styled: ^11.10.5 => 11.10.5
    @mui/base:  5.0.0-alpha.116
    @mui/core-downloads-tracker:  5.11.7
    @mui/icons-material: ^5.11.0 => 5.11.0
    @mui/joy: ^5.0.0-alpha.64 => 5.0.0-alpha.65
    @mui/material: ^5.11.6 => 5.11.7
    @mui/private-theming:  5.11.7
    @mui/styled-engine:  5.11.0
    @mui/system:  5.11.7
    @mui/types:  7.2.3
    @mui/utils:  5.11.7
    @mui/x-data-grid:  5.17.22
    @mui/x-data-grid-pro: ^5.17.22 => 5.17.22
    @mui/x-license-pro:  5.17.12
    @types/react: 18.0.27 => 18.0.27
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: 4.9.4 => 4.9.4

I used Chrome 109.

Order ID 💳 (optional)

59183

@toyi toyi added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Feb 4, 2023
@toyi toyi changed the title updateRows triggers renderCell to many times updateRows triggers renderCell too many times Feb 4, 2023
@zannager zannager added component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user labels Feb 6, 2023
@m4theushw
Copy link
Member

You need to wrap your custom renderCell in React.memo also passing a custom propsAreEqual callback checking only if the relevant props were changed. For instance, in the example provided you only use the value from the params, so you need to re-render if this specific prop has changed.

const CustomCellRenderer = ({ value }) => {
  return value;
};

const MemoizedCellRenderer = React.memo(
  CustomCellRenderer,
  (prevProps, nextProps) => {
    return prevProps.value === nextProps.value;
  }
);

const columns = [
  {
    field: 'id',
    renderCell: (params) => {
      return <MemoizedCellRenderer {...params} />;
    },
  },
];

By doing so, you can substantially reduce the number of times that the custom cell is re-rerended. renderCell will still be called many times but it won't be a problem. Here's the full example: https://stackblitz.com/edit/react-ts-l6yem3?file=App.tsx

@m4theushw m4theushw removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Feb 6, 2023
@m4theushw m4theushw changed the title updateRows triggers renderCell too many times [data grid] updateRows triggers renderCell too many times Feb 6, 2023
@toyi
Copy link
Author

toyi commented Feb 7, 2023

@m4theushw Thank you. It helps, the performances are better, even if it feels tedious and can be difficult to implement in more complex use cases. It doesn't feel "right", you see what I mean?

It seems to be really easy to stumble upon this performance problem, since it manifests itself quickly with not-so-large-and-complex tables.

If there is no plan to fix this behavior in the foreseeable future, it could be worth it to mention this workaround in the doc don't you think?

@m4theushw
Copy link
Member

I understand your pain, however, since we allow to use custom cell renderers (with renderCell) we can't memoize the cell components. If a custom cell renderer depends on part of the state that doesn't update at the same time that one of its received props, this cell will render outdated content. I've been working in #7846 to allow to memoize cells and other components. This has the potential to solve the problem you mentioned with apiRef.current.updateRows. I'll close this issue because it describes the same problem of #7807. In #7807 (comment) I added a preview of the fix I'm working on. If you want to check the CodeSandbox feel free to give us feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! performance plan: Pro Impact at least one Pro user
Projects
None yet
Development

No branches or pull requests

4 participants