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

[DataGrid] Dynamic virtualization range #12353

Merged
merged 39 commits into from
Mar 20, 2024
Merged

Conversation

romgrk
Copy link
Contributor

@romgrk romgrk commented Mar 6, 2024

Closes #11344

Implement both improvements proposed in the linked issue. Read the comments below for more implementation details.

Before: https://deploy-preview-12349--material-ui-x.netlify.app/x/react-data-grid/#pro-plan
After: https://deploy-preview-12353--material-ui-x.netlify.app/x/react-data-grid/#pro-plan

Before/After:

Kooha-2024-03-10-20-48-32.webm

image

@romgrk romgrk added the component: data grid This is the name of the generic UI component, not the React module! label Mar 6, 2024
Comment on lines 160 to 165
const dy = scrollPosition.current.top - previousScroll.current.top;
const dx = scrollPosition.current.left - previousScroll.current.left;
scrollCache.buffer = {
top: dimensions.rowHeight * 10,
left: 50 * 3,
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried predicting* the optimal buffer size but failed, so I just put a static 10 rows or 3 columns buffer.

*I had code in place to collect scroll points as event, which I hoped we could run some math on to figure out where the next scroll event would be. I tried linear regression, polynomial regression, and even a small (<1kb) ML model (simple perceptron architecture) with synaptic.js, but the problem is the data. One would expect scroll events to mostly fit to a bell curve. Which they do as a whole. But the intervals and delta values are just too irregular from one point to the next to be able to predict the next point in a sequence. I have gathered some data (me scrolling the grid) and plotted it here, the last graph is an example of "generally like a bell curve but unpredictable from one point to the next". Maybe with wheel events added in the mix we could get a better error rate (best I could get was 50% error on average), but that will take some more research.

Copy link
Member

Choose a reason for hiding this comment

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

I can't access the link attached. Could you update the permissions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@romgrk romgrk marked this pull request as ready for review March 9, 2024 01:21
Comment on lines 131 to 139
* Column region to render before/after the viewport
* @default 100
*/
columnBuffer: number;
columnBufferPx: number;
/**
* Number of extra rows to be rendered before/after the visible slice.
* @default 3
* Row region to render before/after the viewport
* @default 100
*/
rowBuffer: number;
rowBufferPx: number;
Copy link
Contributor Author

@romgrk romgrk Mar 9, 2024

Choose a reason for hiding this comment

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

I don't love the new name with a Px suffix, but leaving the name as is didn't feel like a good option because it would silently make the grid less performant for the users using this prop.

Copy link
Member

Choose a reason for hiding this comment

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

rowBufferRegion could be another option, JSDoc can explain the unit of the region (px)

Comment on lines 46 to 60
enum ScrollDirection {
NONE,
UP,
DOWN,
LEFT,
RIGHT,
}

const EMPTY_SCROLL_CACHE = {
direction: ScrollDirection.NONE,
lastTimestamp: -1,
lastPosition: { top: 0, left: 0 },
buffer: { top: 0, left: 0 },
};
type ScrollCache = typeof EMPTY_SCROLL_CACHE;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The general idea for the logic is that scroll events trigger right after a new frame has been rendered, so too late for us to prevent white areas that way. If we want to prevent white areas, we need to diplay enough rows/columns so that there is enough of them to cover the area from the current viewport to where the viewport will be at the next scroll event.

As mentioned above predicting by how much the user will have scrolled at the next scroll event is a problem is itself, but by having a substantially large buffer in one direction we try to ensure users see as few white areas as possible.

Copy link
Member

@MBilalShafi MBilalShafi left a comment

Choose a reason for hiding this comment

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

Nice improvement 🚀
Looks smoother

packages/x-data-grid/src/DataGrid/DataGrid.tsx Outdated Show resolved Hide resolved
Comment on lines 131 to 139
* Column region to render before/after the viewport
* @default 100
*/
columnBuffer: number;
columnBufferPx: number;
/**
* Number of extra rows to be rendered before/after the visible slice.
* @default 3
* Row region to render before/after the viewport
* @default 100
*/
rowBuffer: number;
rowBufferPx: number;
Copy link
Member

Choose a reason for hiding this comment

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

rowBufferRegion could be another option, JSDoc can explain the unit of the region (px)

docs/data/data-grid/demo/FullFeaturedDemo.js Outdated Show resolved Hide resolved
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 10, 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 Mar 10, 2024
romgrk and others added 4 commits March 13, 2024 11:36
…-v6.md

Co-authored-by: Andrew Cherniavskii <andrew.cherniavskii@gmail.com>
Signed-off-by: Rom Grk <romgrk@users.noreply.github.com>
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 14, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 17, 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 Mar 19, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 19, 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 Mar 20, 2024
@romgrk romgrk merged commit 1418ac2 into mui:next Mar 20, 2024
17 checks passed
@romgrk romgrk deleted the feat-virtualization-range branch March 20, 2024 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change component: data grid This is the name of the generic UI component, not the React module! performance v7.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DataGrid] Performance: Improve virtualization overscan logic
4 participants