-
-
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] Implement Lazy loading #5214
Conversation
These are the results for the performance tests:
|
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoader.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoader.ts
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/rows/useGridRows.ts
Outdated
Show resolved
Hide resolved
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
docs/data/data-grid/rows/rows.md
Outdated
You can find out more information about how to do that on the [server-side filter page](/components/data-grid/filtering/#server-side-filter) and on the [server-side sorting page](/components/data-grid/sorting/#server-side-sorting). | ||
::: | ||
|
||
{{"demo": "LazyLoadingGrid.js", "bg": "inline", "disableAd": true}} |
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.
After reading this section and the demo, I'm wondering how often the onFetchRows
is called and should I handle by myself to do not call the server if I already have all the rows
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.
If all the rows are loaded the onFetchRows
won't be called.
One optimization that is needed by the user is to implement throttle because now this callback is being called a lot while scrolling.
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.
It seems to fetch for each row that becomes visible in the viewport. In practice, it's probably not usable in production in the current shape as it would flood the server API.
packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoader.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoader.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoader.ts
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid-pro/src/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/hooks/features/rows/useGridRows.ts
Outdated
Show resolved
Hide resolved
Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
….test.tsx Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
packages/grid/x-data-grid/src/hooks/features/rows/useGridRows.ts
Outdated
Show resolved
Hide resolved
I have pushed a simplified version of the demo, aiming to be as close as possible to how developers might fetch the data server-side. It fixes the double fetch flickers. However, it seems that we have a couple of issues. A summary of what I think is off, by order of importance (to complement the existing open comments on lines of code):
I get now the amount of complexity there is in something like https://ag-grid.com/javascript-data-grid/server-side-model/, why it's not MIT. |
Ok, I've pushed the solution a bit more and cleaned most of the issues.
Should be fixed now
I left it like this intentionally. We can add a line in the doc that advises the developers to implement either throttle or debounce themselves. Adding this functionality as part of the feature increases the complexity quite a lot.
I guess this will be added once the Core adds that prop?
Can't this be solved the same way We can merge this version and see what the feedback will be. We can continue to polish it more but it's been quite a long time and I feel we are operating based on assumptions. Not that it is wrong but I would love to start a clean PR after we get some real-world use cases/bugs 😅 |
@DanailH Great, thanks for looking into it! I have found a few more issues on https://deploy-preview-5214--material-ui-x.netlify.app/x/react-data-grid/row-updates/#lazy-loading. a. When sorting, the rows updates twice: Screen.Recording.2022-08-25.at.17.57.57.movb. When opening the filtering panel with an active sort, the rows change: Screen.Recording.2022-08-25.at.17.58.55.movc. When filtering with an active sort, there are rows that shouldn't match Screen.Recording.2022-08-25.at.18.02.30.movAnd I think that it's :). It might be an issue with the demo, and not the source.
It's definitely more complex, but I also think why we should care. It's precisely for the hard problems that developers will come to use our stuff. My main concern is: Are we shipping a demo that can't be used in production and with APIs that are not From what I understand, if a developer uses https://deploy-preview-5214--material-ui-x.netlify.app/x/react-data-grid/row-updates/#lazy-loading as is, he will DDoS his backend and will show rows to his end-users that don't match what they filter for (out-of-sync). So I would expect that he will need to do further work to solve 2. and 3 on his own. Since we know it, I think that we should fix it before we tell them to use the demo. I'm afraid that if we don't, we might harm the trust that developers have in their ability to copy & paste from the demo in the docs. Since the problem is complex, 💯 to only fix it in the demo. It will give us time to find an API that can then accommodate tree data, pivoting, etc.
We could wait for mui/material-ui#34057. However, I think that it would be great to first dogfood this idea inside MUI X, both to find an implementation that works well, and to prove that it brings value, and that it deserves to be in the core. I think that it could be a follow-up PR 👍 . It's kind of detail, a lot less important than the previous points. Edit: It seems that this other demo https://mui.com/x/react-data-grid/row-updates/#infinite-loading is also not usable in production as is. The filtering and sorting are not working and the demo is not this straightforward to convert into network API calls. I would be in favor of working on this, considering AG Grid demos seem directly usable. |
Alright, I added the last changes:
Regarding the problems with the demo - I guess it's a limitation with what we have in terms of the fake server. It needs additional polishing but that can be done later on in a clean PR. I will merge this PR as it states it is stable in terms of the lazy loading feature and the replace rows API. Thank you @oliviertassinari for the detailed review and feedback. |
#1247
Preview -> https://deploy-preview-5214--material-ui-x.netlify.app/x/react-data-grid/row-updates/#lazy-loading
How does it work?
The approach is fairly straightforward. The new virtualization does make solving this problem more easily. The solution still doesn't on the
scrollTop
. It reacts when there are changes of therenderContext
and emits an event that is handled by theuseGridLazyLoader
feature hook.There is a small logic that finds the section between 2 given indexes of the rows array and only passes down to the user the start and end index of the rows that hadn't been loaded yet (skeleton rows).
The more interesting part is how the skeleton rows are being rendered. There is a pre-processor that adds logic to the
hydrateRows
. When the lazy load feature is enabled the pre-processor runs and it checks if there is a difference between the number of provided rows and therowCount
set by the user. If there is a difference then "empty" (skeleton rows, with only auto-generatedid
and nomodel
added to the state). There is a small logic in theGridRow.tsx
that handles the case where a row has nomodel
and renders skeleton cells instead ofGridCell.tsx
component.Last but not least, there is a new API method in the
useGridRows
that replaces a set of rows between 2 given indexes with a user-provided set. This is how the new rows are "loaded".ToDo: