Hi there,
I know that this is a big topic, but I will ask/comment anyway. Others might benefit as well.
The selection logic that kendogrid uses is not performant enough.
On every selection basically everything is re-rendered:
- All rows. (GridRow)
- All cells for all rows. (GridCell)
- The header
- The toolbar
This works well enough when there are a few records - 10-20-50.
With more records the performance degrades too much.
To improve performance:
- I used React.memo for the cells
However, the rows (GridRow),header,toolbar are still re-rendered. When I have 100-200 and more records that's too much.
You provide virtual scrolling, but it has the following disadvantages:
1. You have to have a fixed row height. For my application this is too restrictive. I need to have variable row height.
2. You cannot use paging with virtual scrolling. (I might be able to hack a custom paging solution or do not use paging. But even then the fixed row height is too restrictive)
I am going in the direction of using something like react-visible, to detect which rows are off-canvas and avoid rendering them.
Do you have any other suggestions?
Do you plan on optimizing the grid performance? I can wait a few months for a better solution coming from you.
How can I override the GridRow component for the grid? There is a hook rowRender (or renderRow, don't remember). I tried returning a ReactNode from it, but it didn't work (the app crashes)? Can you please provide an example how can I do that?
6 Answers, 1 is accepted
Hello, Venelin,
Thank you for all of the details.
In general, even if the render is called multiple times due to the React virtual DOM the updates should be very minimal.
Still, we have made an example with React.useMemo for the rowRender to optimize it. Depending on the functionalities of the Grid, please make sure to pass the correct parameters to the useMemo function, to not stop necessary updates:
https://stackblitz.com/edit/react-qed7me-warzeh?file=app/main.jsx
If this is still not an option, the selection can be made directly using DOM operations to update the classList of a single DOM element instead of re-render. This is not the "React way", but it can improve the performance in this specific use case.
I hope this will prove helpful.
Regards,
Stefan
Progress Telerik
Hi.
I'm solving the same problem as Venelin. And I'm confused. Because when I tried to solve the problem locally, nothing improved. I'm looking at your example of stackblitz. Imho, map is mutable change - data is always different. When I look in the console, your example also shows that x renders happen there, after clicking on a row. The second click on the next line has exactly 2x more line renders. Am I doing anything wrong? Because I have a real problem, just about 100 lines and click on the line in the grid and the delay is noticeable. And I don't like the no-react solution. Well thank you.
Hello, Igor,
I assume someone made a change to an example accidentally.
The memo should be updated only based on a specific value, for example, the ID was changed or the selected value.
const CurrentRow = React.useMemo(() => {
console.log('>>row render');
return React.cloneElement(row, { ...others, onClick: onClick, onDoubleClick:onDoubleClick}, row.props.children);
}, [others.dataItem.selected]);
https://stackblitz.com/edit/react-qed7me-warzeh?file=app/main.jsx
This should update only the changed rows.
Also, we have an official improvement already on a pull request, that resolves this automatically. We expect it to be live in the next couple of weeks.
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thank you Stefan.
Your edit helped.
But the console also shows a lot of warnings in your example. So do me locally. I can't handle it.
Thanks.
I'm not sure. Maybe I solved it.
I think the props in the <CustomComponent /> component should not be {... props}, but {... row.props}. And the specific value for useMemo hook needs to be sent differently.
Hello, Igor,
Yes, the warning is because we are setting all props to the TR element and they are invalid attributes.
This requires setting only the required props to the TR.
If there are any issues, please let me know and I will be happy to assist.
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.