-
-
Couldn't load subscription status.
- Fork 1.7k
Description
Steps to reproduce
Steps:
- Use ThemeProvider to customize the theme. The theme variable is defined inside the component.
- The theme object includes a React element.
Demo.tsx
import { DataGridPro } from '@mui/x-data-grid-pro';
import { useDemoData } from '@mui/x-data-grid-generator';
import { createTheme, ThemeProvider } from '@mui/material';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
export default function Demo() {
const { data, loading } = useDemoData({
dataSet: 'Commodity',
rowLength: 1000,
editable: true,
});
const theme = createTheme({
components: {
MuiCheckbox: {
defaultProps: {
icon: <CheckCircleIcon />,
},
},
},
});
return (
<ThemeProvider theme={theme}>
<DataGridPro
{...data}
pagination
loading={loading}
initialState={{
pagination: {
paginationModel: { pageSize: 5 },
},
}}
pageSizeOptions={[5]}
/>
</ThemeProvider>
);
}Current behavior
source code: https://github.com/mui/mui-x/blob/master/packages/x-internals/src/hash/stringify.ts
Executing the stringify function within the DataGrid is slow when the theme object contains React Elements. This is because a React Element (or more specifically, its underlying FiberNode) is a large object, which leads to slow execution and the generation of a large string. Additionally, the execution speed of the hash function will also be slow.
Based on my testing, the execution of the hash and stringify functions takes 10ms even for the simplest demo. For more complex pages, the execution time increases severalfold. This multiplicative effect is also observed on pages with multiple DataGrid components. This leads to slow rendering of the DataGrid component, which in turn results in poor page load performance.
Expected behavior
I suggest changing the stringify implementation. During JSON.stringify, if a value is a React element, we should return undefined to omit it from the result. This would prevent the expensive serialization of the React element. While this should improve performance, I’m not sure what potential side effects it might introduce.
+ import * as React from 'react';
export function stringify(input: object | string | number | null) {
const seen = new WeakSet();
return JSON.stringify(input, (_, v) => {
// https://github.com/mui/mui-x/issues/17855
if (
(typeof window !== 'undefined' && v === window) ||
(typeof document !== 'undefined' && v === document)
) {
return v.toString();
}
if (v !== null && typeof v === 'object') {
+ if (React.isValidElement(v)) {
+ return;
+ }
if (seen.has(v)) {
return null;
}
seen.add(v);
}
return v;
});
}Context
No response