kendoreact grid selection performance

7 posts, 0 answers
  1. Venelin
    Venelin avatar
    6 posts
    Member since:
    Jun 2019

    Posted 20 Nov 2019 Link to this post

    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?

     

     

     

  2. Stefan
    Admin
    Stefan avatar
    3039 posts

    Posted 20 Nov 2019 Link to this post

    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

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Igor Stanek
    Igor Stanek avatar
    18 posts
    Member since:
    Jan 2008

    Posted 18 Nov 2020 in reply to Stefan Link to this post

    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.

  4. Stefan
    Admin
    Stefan avatar
    3039 posts

    Posted 19 Nov 2020 Link to this post

    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/.

  5. Igor Stanek
    Igor Stanek avatar
    18 posts
    Member since:
    Jan 2008

    Posted 19 Nov 2020 in reply to Stefan Link to this post

    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.

  6. Igor Stanek
    Igor Stanek avatar
    18 posts
    Member since:
    Jan 2008

    Posted 19 Nov 2020 in reply to Igor Stanek Link to this post

    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.

  7. Stefan
    Admin
    Stefan avatar
    3039 posts

    Posted 20 Nov 2020 Link to this post

    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/.

Back to Top