Search code examples
javascriptreactjstypescriptreact-window

Rendering a large list of varying width elements that are floated to the left


I am trying to get react-window to work with a list of float: left buttons in a resizable, scrollable window.

I have a list like the following (all with bootstrap styled buttons floated left)

|[--1--][-2-][----3----][--4--].......|
|[---5---][-6-][-----7-----][-8-].....|
|[------9------][----10----]..........|

Built from an array of objects, however when the items start reaching the thousands (i am currently trying with a list of 6000), the render time turns to ~900ms for the list, and everything in the application turns to a 2fps mess.

From my understanding react-window requires the height to be known but i currently dont know of a way to get the height without actually rendering them which i believe is the problem.

I have managed to get a react-window list working like the following

|[--1--]..................|
|[-2-]....................|
|[----3----]..............|
|[--4--]..................|
|[---5---]................|
|[-6-]---]................| // This line isn't an error, sometimes text wrapping makes the button double height but it just goes underneath the next row.
|[-----7-----]............|
|[-8-]....................|
|[------9------]..........|

In which the performance is more of what i am expecting of the list, however that doesnt match the design i am going for. I have been searching for way to long with no end in sight.

An additional gotcha is that the width of the container is resizable.

What are the options (if any) to get this to work, or any examples of similar lists that i can try recreate.


Solution

  • I have decided to go with the approach of loading 100 items, then loading another 100 when the user scrolls to the bottom, etc. It still isn't as good as the react-window list, but a lot better than nothing.

    I also have used elementRef.current.scrollHeight <= elementRef.current.clientHeight to load items at the start until the scroll bar appears.

    Hopefully posting an answer like this is the right thing to do (i figured leaving the question empty would be worse)