-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[data grid] Poor performance with TreeData and large dataset #17389
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
Comments
@amannan-bucs |
Hi @arminmeh, Thanks for looking into this! Given that, I'd really appreciate any guidance on optimizing performance with these props in place. Are there known best practices or workarounds for improving render efficiency when using custom renderers with treeData? If there's anything that can help in this matter, we'd love to hear about it. Looking forward to any further insights you uncover. |
So, the main problem here is that you use state ( If you extract the grouping cell render: const RenderGroupingCell = (params: GridRenderCellParams) => {
const { id, rowNode, value } = params;
const apiRef = useGridApiContext();
const [isExpanded, setIsExpanded] = React.useState(
rowNode.type === 'group' && rowNode?.childrenExpanded,
);
const handleToggle = React.useCallback(() => {
setIsExpanded((prev) => !prev);
apiRef.current?.setRowChildrenExpansion(id, !isExpanded);
}, [apiRef, isExpanded]);
return (
<FlexBox alignItems={'center'} flex={1} margin={'0px -10px'} height={'100%'}>
{rowNode.type === 'group' && (
<IconButton onClick={handleToggle}>
<ExpandMoreIcon
sx={(theme) => ({
fontSize: 20,
transform: `rotateZ(${isExpanded ? 0 : -90}deg)`,
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
})}
fontSize="small"
/>
</IconButton>
)}
<Typography fontSize={14} sx={{ ml: 1 }} fontWeight={600}>
{value}
</Typography>
</FlexBox>
);
}; ... and use With this the bottleneck should be gone |
@michelengelen I've implemented the solution you suggested in your last comment. Unfortunately, it hasn't significantly improved the performance lag we're experiencing. We're using expandedRowId because our grid is editable. When a row enters edit mode or an update is made, the expanded row collapses due to a re-render happening behind the scenes. To avoid this behavior, we need to explicitly manage the expanded state of the group. Please take a look at the updated code in the live demo, which reflects your recommendations. Since the performance hasn't improved noticeably, I'd appreciate it if you could take another look and let me know if there are any other potential bottlenecks or optimizations we might be missing. Thanks! |
Since Codesandbox Demo is not working, I have added the code in another GitHub repository for you to have a look. Please take a look at following repo: |
The sandbox was working for me. const RenderGroupingCell = (params: GridRenderCellParams) => {
const { id, rowNode, value } = params;
const apiRef = useGridApiContext();
const [isExpanded, setIsExpanded] = React.useState(
rowNode.type === 'group' && rowNode?.childrenExpanded,
);
const handleToggle = React.useCallback(() => {
setIsExpanded((prev) => !prev);
apiRef.current?.setRowChildrenExpansion(id, !isExpanded);
}, [apiRef, isExpanded]);
return (
<FlexBox alignItems={'center'} flex={1} margin={'0px -10px'} height={'100%'}>
{rowNode.type === 'group' && (
<IconButton onClick={handleToggle}>
<ExpandMoreIcon
sx={(theme) => ({
fontSize: 20,
transform: `rotateZ(${isExpanded ? 0 : -90}deg)`,
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
})}
fontSize="small"
/>
</IconButton>
)}
<Typography fontSize={14} sx={{ ml: 1 }} fontWeight={600}>
{value}
</Typography>
</FlexBox>
);
};
// extract the grouping column definition, pinnedColumns and getTreeDataPath
// prop values to create stable references
const MDR_GROUPING_COL_DEF = {
headerName: 'Commodity',
minWidth: 320,
flex: 1,
sortable: true,
hideDescendantCount: true,
hideable: false,
leafField: 'commodity',
renderCell: RenderGroupingCell,
};
const pinnedColumns = {
right: ['actions'],
};
const getTreeDataPath: DataGridProProps['getTreeDataPath'] = (row) => {
return [row.commodity, row.id];
};
export default function DataGridProDemo() {
const gridApiRef = useGridApiRef();
const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>({});
const expandedTreeRowId = React.useRef<GridRowId | null>(null);
const { data, loading } = useDemoData({
dataSet: 'Commodity',
rowLength: 95000,
editable: true,
});
// use ref instead of state to decrease number of re-renders due to state updates
React.useEffect(() => {
return gridApiRef.current?.subscribeEvent('rowExpansionChange', (params) => {
const { id } = params;
const rowNode = gridRowNodeSelector(gridApiRef, id);
if (rowNode.type === 'group') {
expandedTreeRowId.current = rowNode?.isExpanded ? id : null;
}
});
}, [gridApiRef]);
// wrap it in useCallback to make the reference more stable
const checkIsGroupExpandedByDefault: DataGridProProps['isGroupExpandedByDefault'] =
React.useCallback(
(node: GridGroupNode) => expandedTreeRowId.current === node.id,
[expandedTreeRowId.current],
);
return (
<Box sx={{ height: 520, width: '100%' }}>
<DataGridPro
{...data}
treeData
checkboxSelection
disableRowSelectionOnClick
apiRef={gridApiRef}
columns={data.columns}
loading={loading}
getTreeDataPath={getTreeDataPath}
isGroupExpandedByDefault={checkIsGroupExpandedByDefault}
groupingColDef={MDR_GROUPING_COL_DEF}
rowModesModel={rowModesModel}
onRowModesModelChange={setRowModesModel}
rowHeight={38}
pinnedColumns={pinnedColumns}
editMode="row"
/>
</Box>
);
} Could you try that as well? |
@michelengelen, most of the improvements you suggested were already implemented in my actual project. I’ve now also applied the remaining suggestions—both in the main project (including similar enhancements across other custom renderers) and in a live CodeSandbox for your reference. That said, the performance gains are still quite minimal. The grid and tree data remain noticeably slow, even in the test project. Could you please take another look when you have a moment? Additionally, I created a separate project without any custom renderers, and its performance is noticeably better. However, as mentioned earlier, our actual project requires these custom renderers to meet specific business and UI/UX needs. Here’s the link to the other project: |
@arminmeh could you also have another look if we can improve something on the demo? |
I have extracted more things outside of the component to make the references more stable and avoid explicit memoization. Performance is still not perfect, but I think that it has improved a lot |
Hi @arminmeh , Thanks for looking into this. I’ve reviewed the improvements you’ve made and incorporated them into our actual project. Unfortunately, as you also pointed out, the performance is still not satisfactory. Our real implementation includes additional features that aren't present in the demo but are necessary to meet our UI/UX and business requirements. Given the current performance limitations, we’re unable deliver the feature with these performance lags. Is there any alternative approach we could explore to achieve significantly better performance when using DataGrid with tree data/grouping on larger datasets? |
Any update on this please? |
Uh oh!
There was an error while loading. Please reload this page.
Steps to reproduce
Steps:
Current behavior
The DataGrid becomes significantly slow and unresponsive when interacting with TreeData on large datasets (50,000+ rows), even with virtualization enabled. Actions like toggling expand/collapse and scrolling are particularly affected.
Expected behavior
The grid should remain responsive and fluid during all interactions — including editing, scrolling, and expanding TreeData — even with large datasets. This is crucial for our production use case, where users frequently work with tens of thousands of records in real time.
Context
We are building a highly interactive data table that allows users to view, edit, and manipulate large datasets seamlessly. Performance is a critical factor for usability, and current slowness is a blocker in adopting this component for our needs. We expect virtualization to handle these volumes more efficiently.
Your environment
npx @mui/envinfo
Search keywords: data-grid-pro, data-grid-treedata, performance, large-dataset
Order ID: 102733
The text was updated successfully, but these errors were encountered: