-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[DataGridPro] Improve treeData
and rowGrouping
performance
#8990
[DataGridPro] Improve treeData
and rowGrouping
performance
#8990
Conversation
Netlify deploy previewNetlify deploy preview: https://deploy-preview-8990--material-ui-x.netlify.app/ Updated pagesNo updates. These are the results for the performance tests:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad that this fix solves the performance problem that well !
I am a little worried about the idea of mutating the children
property (childrenFromPath
less so, it's never used outside of the tree-building process).
Because now if you have a useMemo
in a component that relies on rowNode.children
, it won't re-run on tree updates.
My proposal was to do one spread per parent instead of one spread per children.
Not sure how to do that cleanly in the code.
We could pass a prevTree
object that equals the tree before the current batch and only spread if prevTree[parentNode.id].children === tree[parentNode.id].children
.
Could even be |
Thanks @flaviendelangle for the suggestions, I tried to do a comparison with the
If you have any example in mind (or on docs) using which I can validate that this use case works as expected now, please share. I didn't quite get that in what circumstances a user would need to memoize |
Is it working or is it causing some issue ?
When providing a custom If you look at the demo const lastHired = React.useMemo(() => {
return rowNode.children.reduce((acc, el) => {
if (!acc || acc.recruitmentDate.getTime() < el.recruitmentDate.getTIme()) {
return el
}
return acc
}, null)
}, [rowNode.children]) And then we render this I honestly don't think a lot of people are using |
Apparently it seems to be working, I will try with the example you mentioned. 👍 |
}, | ||
children: [...parentNode.children, node.id], | ||
}; | ||
if (previousTree !== null && previousTree[parentNode.id] === tree[parentNode.id]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing previousTree
everywhere doesn't look great, but I don't really see a better option 🤨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative is to create a dictionnary that contains all the updated nodes during a batch.
But same problem, we end up having an additional param all over the place.
Does this one fix #8999? |
@flaviendelangle I confirmed, the mentioned use-case seems to work fine: https://codesandbox.io/s/keen-spence-hqg9q4?file=/demo.tsx (note the new date correctly being picked of children)
It does, on my test (MacOS, Chrome v113), the time to render the grid (for 100,000 rows) reduced from 22s to 0.8s Before: https://codesandbox.io/s/aggregation-performance-regression-zx0rrd?file=/src/App.tsx I think, after this change, MUI Grid will be the fastest to render this much aggregation rows among the mentioned competitors on #8999 🎉 |
treeData
in v6treeData
and aggregation
in v6
For the title, it improved the row grouping and the tree data |
treeData
and aggregation
in v6treeData
and rowGrouping
in v6
treeData
and rowGrouping
in v6treeData
and rowGrouping
performance
Fixes #8581
The regression was introduced due to a function createRowTree introduced in the new internal structure for v6.
Initial benchmarks:
For the same data (size: 40000), (i.e the one used in the linked codesandbox)
Reason:
Looking deeper into the main function being used in createRowTree (i.e. insertNodeInTree) there are not many complex computations apart from some references being updated.
Doing a comparison yielded that most of the time is being consumed in destructuring and updating references of variables
childrenFromPath
andchildren
, so avoiding that and keeping the same reference improved the performance.Updated Benchmarks (to render 40000 rows with
treeData
):Macbook Pro M1, Chrome browser:
v5 version: ~2s
v6 version (HEAD): ~10s
v6 version (this PR): ~1.8s
Macbook Pro M1, Firefox browser:
v5 version: ~8.5s
v6 version (HEAD): ~13s
v6 version (this PR): ~8.9s
Side note: Chromium v8 seems to handle reference-based assignments way faster than Firefox, the performance on Chrome seems improved from the v5 version.
Fixes #8999
On my test (MacOS, Chrome v113), the time to render the grid (for 100,000 rows) reduced from 22s to 0.8s
Before: https://codesandbox.io/s/aggregation-performance-regression-zx0rrd?file=/src/App.tsx
After: https://codesandbox.io/s/aggregation-performance-regression-fixed-x7k6gm?file=/src/App.tsx