Skip to content
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

[data grid] Performance: separate row cleanup #12023

Closed
wants to merge 41 commits into from

Conversation

romgrk
Copy link
Contributor

@romgrk romgrk commented Feb 10, 2024

Stacked on #12013 and #12019 to explore #11866

Experiment with scrolling performance.

The idea behind this is that most of our scroll event callback runtime is spent removing DOM nodes, while appending new ones is much less expensive. This is a characteristic of the DOM spec and outside of our control. The graph below shows the amount of time spent adding new rows (green) and removing old rows (red). Other virtualized grids such as AG-grid have the same performance profile. The goal here is to try to remove the red section from the flushSync path, and try to pay that cost at a different moment, possibly with requestIdleCallback.

image

Before: https://next.mui.com/x/react-data-grid/virtualization/#column-virtualization
After: https://deploy-preview-12023--material-ui-x.netlify.app/x/react-data-grid/virtualization/#column-virtualization

Changes

  • Rendered rows are stored in a RowIntervalList, an interval list data structure that holds row indexes and their render context.
  • Avoid colSpan computations in scroll event, those are very expensive and unnecessary unless there is a .colSpan somewhere
  • Rows and detail panels are now position: absolute; top: ... positioned.

@romgrk romgrk added the component: data grid This is the name of the generic UI component, not the React module! label Feb 10, 2024
@mui-bot
Copy link

mui-bot commented Feb 10, 2024

Deploy preview: https://deploy-preview-12023--material-ui-x.netlify.app/

Generated by 🚫 dangerJS against f82c480

removalList.nodes.at(0)!.start + CLEANUP_ROWS,
);
} else {
removalList.keep(removalList.nodes.at(0)!.end - CLEANUP_ROWS, removalList.nodes.at(0)!.end);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Index should be -1, not 0

Comment on lines +28 to +30
export function useIdleCallback() {
return useLazyRef(createIdleCallback).current;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unmount cleanup logic?

romgrk and others added 2 commits February 12, 2024 20:24
Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
Signed-off-by: Rom Grk <romgrk@users.noreply.github.com>
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 15, 2024
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 23, 2024
@romgrk
Copy link
Contributor Author

romgrk commented Feb 23, 2024

I've finished implementing the cleanup logic, here is a quick performance comparison. The new implementation does its cleanup after 1s without user interaction.

Kooha-2024-02-22-23-04-28.webm

@romgrk romgrk changed the title [data grid] Performance: scrolling experiment [data grid] Performance: separate row cleanup Feb 23, 2024
@oliviertassinari
Copy link
Member

I've finished implementing the cleanup logic, here is a quick performance comparison. The new implementation does its cleanup after 1s without user interaction.

@romgrk When I run #11866 (comment), the benchmark, and UX is noticeably worse on this PR. Not sure it's working 😁

@romgrk
Copy link
Contributor Author

romgrk commented Feb 26, 2024

Weird results, this PR makes it smoother for me. Any chance you can send me a recording and a profile of the benchmark? (the "Save profile..." button in the Performance tab)

@cherniavskii
Copy link
Member

@romgrk I can reproduce this as well. It gets slower the more you scroll:

https://next--material-ui-x.netlify.app/x/react-data-grid/#pro-plan

Screen.Recording.2024-02-26.at.12.46.20.mov

https://deploy-preview-12023--material-ui-x.netlify.app/x/react-data-grid/#pro-plan

Screen.Recording.2024-02-26.at.12.46.49.mov

Here's the profile: https://drive.google.com/file/d/1in_kUcfi9s4_zv06mobVPAPNsXjCzPTT/view?usp=drive_link

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 27, 2024
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 28, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 28, 2024
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@romgrk
Copy link
Contributor Author

romgrk commented Mar 5, 2024

I WAS WRONG.

Anyway long story short I have a benchmarking chrome user-profile that is usually clean (no react-dev-tools extension or anything else that affects runtime performance) so I can benchmark precisely. Well I had activated the devtools experimental flag Timeline: invalidation tracking a few weeks back for the other performance issues (style recalculation). Turns out it was slowing down considerably the removeChild operation but only in profiling mode, which I had been running in the whole time while benchmarking this PR. So yes, the row cleanup thing is useless.

There's a few other performance improvements on this PR that I'll pick up separately.

@kurtextrem
Copy link

@romgrk maybe worth reporting as crbug? I'm not sure if it's expected that removeChild becomes slower with invalidation tracking enabled

@romgrk
Copy link
Contributor Author

romgrk commented Apr 1, 2024

Don't think so. Invalidation doesn't just get the experimental warning:

image

It gets an additional 2nd warning about their unstability:

image

@romgrk romgrk deleted the perf-scrolling-complex branch April 1, 2024 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! performance PR: out-of-date The pull request has merge conflicts and can't be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants