mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.56k stars 1.33k forks source link

[data grid] Slow performance of the mui x grid premium when scrolling with sticky columns #15501

Open igortas opened 5 days ago

igortas commented 5 days ago

Current behavior

Mui x grid runs so slow on localhost (even the performance is far better with production build. but still the problem is there), the scroll is laggish, and laggin when I have many colums and sticky headers (column >= 30 and sticky heeaders >=3)

Expected behavior

I expect the grid to works smooth and not working slow and laggish

Context

I'm trying to render table with dynamic number of columns >=40 with lazy loading and >=10.000 rows and sometimes with sticky headers >=3. Optimization with useMemo, useCallback and stable references for some static objects outside of the components, not helping me at all.

Your environment

System: OS: Linux 5.15 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat) Binaries: Node: 22.6.0 - ~/.nvm/versions/node/v22.6.0/bin/node npm: 10.9.0 - ~/.nvm/versions/node/v22.6.0/bin/npm pnpm: 9.13.2 - ~/.local/share/pnpm/pnpm Browsers: Chrome: Not Found npmPackages: @emotion/react: ^11.13.5 => 11.13.5 @emotion/styled: ^11.13.5 => 11.13.5 @mui/icons-material: ^6.1.7 => 6.1.7 @mui/lab: ^6.0.0-beta.15 => 6.0.0-beta.15 @mui/material: ^6.1.7 => 6.1.7 @mui/x-data-grid-premium: ~7.22.2 => 7.22.2 @mui/x-license: ^7.21.0 => 7.21.0 @mui/x-tree-view: ~7.22.1 => 7.22.1 @types/react: ^18.3.12 => 18.3.12 react: ^18.3.1 => 18.3.1 react-dom: ^18.3.1 => 18.3.1 typescript: ^5.6.3 => 5.6.3

Search keywords: grid, performance

michelengelen commented 5 days ago

Hey @igortas ... could you share your specific implementation? Or at least a stripped down version of it that shows the problem.

I am running a data grid premium on my localhost with 50_000 rows and 30 columns and cannot see major lags (slight banding when scrolling really fast, but thats to be expected).

So if you see any performance problems we can only help you when we can view the code you are trying to implement.

igortas commented 5 days ago

Hi @michelengelen

I managed to improve the performance of the x grid for modals, but I get the issue still when there is much more columns, like 40+ and sticky columns are custom jsx components.

How I can improve the scrolling performance when I'm using getActions for sticky columns and I pass custom components?
Is there a way to conditionally render component inside cells, so when the user hover over some cell change to component, otherwise render only simple icon?

michelengelen commented 4 days ago

Without a reproduction we cannot really help you in your specific usecase, sry.

I have no performance problems with my local instance (in dev mode) running 50_000 rows on 30 columns with pinned rows and columns. In order to help you optimize we need a reproduction.

As for the cell renders: there are a few ways to customize them.

  1. using slotProps
  2. using renderCell
igortas commented 4 days ago

@michelengelen I've started getting slite better performance (but still on localhost is laggish, but I've managed to fix some other instances), i will try to use slotProps for mouse hover as last thing for conditional rendering. renderCell I'm using that prop in very rare ocasions, but in those instances I have very small sets of data, which for now is not problem.

I have a question about the snippet below. Sonarcube, complains about the toolbar and gives me this error: Move this component definition out of the parent component and pass data as props. I'm not sure really how to put the toolbar outside of the x grid wrapper, because I have some dependencies from the props from the shared wrapper, but even I will extract it outside, is there really some performance gain, as sonarcube is complaining?

Also one more question, what is so specific about the examples from the docs and how the data is prepared so the examples are blazing fast? I know in real scenario u have some other components on top of mui x grid, but if per docs stable references and memoization is the key to prevent rerenders and that is done, how than the scroll is lagging, which is happening inside the x grid? What is the first thing to look for slow scrolling?


    const slots = useMemo(
        () => ({
            toolbar: () => (
                <MuiTableToolbar
                    hideEmptyValuesSwitch={hide?.emptyValuesSwitch ?? false}
                    hideToolbar={hide?.toolbar ?? false}
                    selectedRows={selectedRows}
                    deleteToolbarAction={deleteToolbarAction}
                    getRowId={getRowIdCallback}
                />
            ),
            ...toolbarIcons
        }),
        [
            selectedRows,
            deleteToolbarAction,
            hide?.toolbar,
            hide?.emptyValuesSwitch,
            grouping?.leafField
        ]
    );

                <MuiTableToolbar
                    hideEmptyValuesSwitch={hide?.emptyValuesSwitch ?? false}
                    hideToolbar={hide?.toolbar ?? false}
                    selectedRows={selectedRows}
                    deleteToolbarAction={deleteToolbarAction}
                    getRowId={getRowIdCallback}
                />

                               <DataGridPremium slots={slots} ... />
michelengelen commented 3 days ago

@michelengelen I've started getting slite better performance (but still on localhost is laggish, but I've managed to fix some other instances), i will try to use slotProps for mouse hover as last thing for conditional rendering. renderCell I'm using that prop in very rare ocasions, but in those instances I have very small sets of data, which for now is not problem.

That's good to hear. 👍🏼

I have a question about the snippet below. Sonarcube, complains about the toolbar and gives me this error: Move this component definition out of the parent component and pass data as props. I'm not sure really how to put the toolbar outside of the x grid wrapper, because I have some dependencies from the props from the shared wrapper, but even I will extract it outside, is there really some performance gain, as sonarcube is complaining?

Snippets won't do the trick. We need the full (stripped down) and working code in a sandbox to debug. Otherwise we are not able to help very effectively.

Also one more question, what is so specific about the examples from the docs and how the data is prepared so the examples are blazing fast? I know in real scenario u have some other components on top of mui x grid, but if per docs stable references and memoization is the key to prevent rerenders and that is done, how than the scroll is lagging, which is happening inside the x grid? What is the first thing to look for slow scrolling?

The first things to look for are expensive components and functions, if everything is memoized correctly and there are no frequent state updates re-rendering the whole component tree.

Be assured that we did not do any specific adjustments to the docs examples, we just follow the best practices. The scroll lag you experience has to come from your specific implementation. Sry!