-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[DataGrid] Remove try/catch from GridCell
due to performance issues
#15616
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
Conversation
Deploy preview: https://deploy-preview-15616--material-ui-x.netlify.app/ |
GridCell
due to performance issues
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.
LGTM, thanks!
Cherry-pick PRs will be created targeting branches: v7.x |
Did you have a chance to benchmark the perf impact outside of updating rows? This PR introduces an additional Initially I kept the |
getRowParams calls getRow anyways – I doubt calling it twice in a row has any impact in any modern javascript engine. Pretty sure that try/catch would have a higher overhead than that even in a passing case. |
Just did a test in all major browsers – sequential reads are virtually for free. Even when accessing random keys on the same object, but certainly the same key. There's a tiny bit of overhead when Even if a viewport would fit 100 rows, it probably wouldn't register, as only the first row during first access of the object would be the slowest. Theoretically, of course better to return a null. But there are probably lower hanging fruits wrt performance, like fixing memoization, state propagation, and potentially virtualization. While I have you here – have you guys benchmarked your approach to virtualization? Is it a conscious choice performance-wise to transform the whole RenderZone at once vs. individual rows? In theory, the browser may need to do more work painting when individual rows change – larger paintable area + potential containment issues. But haven't benchmarked myself, just a hunch. Most other virtualization implementations I've seen and used have settled on per-row transforms for whatever reason (incl. Ag-grid). |
IIRC, the relevant engines have removed try/catch deoptimizations, so it should be as efficient as normal code as long as it doesn't throw.
I did extensive work on virtualization last year, when we reworked the layout to use CSS sticky headers. Back then I benchmarked heavily a few different approaches (and profiled ag-grid extensively to understand how they perform), including
Yes, there seems to have been perf regressions, back last year the memoization was working correctly. |
You're right about try/catch in case it doesn't throw, my knowledge there was outdated. Appreciate the context about virtualization. It does make some features like dynamic rowHeight also easier to implement I suppose. After thinking a bit more about the getCellParams API, I'm not sure making it return null is necessarily good for DX either. We use it in a few different places in our app code (8 instances), and in every use, it's very explicit that the cell/row does exist. Say, we're focusing in on a cell or hovering it or triggering a context menu on it or copying a value from it, and need to access the cell's props. Why wouldn't it suddenly exist? Then we need to write extra code only to please typescript. We don't have any try catch logic either, and haven't had issues so far at least 🤔. One way or the other, it would be better if the cell value existed until the row has unmounted. |
Should I merge the same changes into v7? #15621 |
From our side, yes please 🙏 |
Fixes the performance issue described in #15615
We had about 150ms of scripting overhead when updating rows fast on typing via external filters (e.g. typing 5 letters, so 5 updates = 150ms in ~1s of user interaction). The larger the viewport, the larger the overhead. After this small change, all of it is gone, and it's mostly layout updates now.