When working on web applications, we often display lists of data. If the data is not particularly lengthy, we are probably okay with rendering all elements at once. However, as our data grows, we might notice performance issues. In this article, we create a simple React application that aims to render thousands of images using a virtualization technique.
While the above solution works, it is far from optimal. Rendering thousands of images at once causes the browser to make thousands of HTTP GET requests to fetch all of the data. Therefore, it is going to cause issues, especially on mobile.
Also, rendering thousands of elements in the DOM tree can slow down the initial rendering of our website and cause the scrolling to stutter.
Let’s run a Lighthouse audit to measure the performance of our application.
Unfortunately, the above score is not very good. So, let’s try improving it.
Introducing virtualization
If we render a large list, the user does not see all its contents at once and uses a scrollbar. When we implement virtualization, we don’t render the elements of the list that are not currently visible. By doing that, we make the DOM tree creation a lot faster. Besides that, the browser does not need to fetch all the images simultaneously.
Thanks to the react-window library, we no longer render all elements at once.
The above, combined with the fact that the browser no longer fetches all of the images, immediately improves our performance significantly.
Sizing the list automatically
So far, we’ve had to provide the width and height of the list explicitly. If we want the list to be sized automatically, we need the react-virtualized-auto-sizer library.
We can use
AutoSizer to manage only width or height instead of both. To do that, we need to use the
disableHeight or
disableWidth attributes.
A crucial thing to notice is that the
AutoSizer expands to fill the parent, but it does not stretch it. In our case, to deal with it in the simplest way possible, we can enlarge the
#root div.
1
2
3
4
#root {
width:100vw;
height:100vh;
}
Implementing pagination
So far, we’ve fetched all data in one big request. However, to improve the performance more and handle the data of any length, we can implement infinite scrolling. The idea is to fetch additional data every time the user scrolls to the end of the list.
Thanks to the above changes, our application loads batches of elements as the user scrolls the list.
Summary
In this article, we’ve tackled the issue of rendering huge lists in React. To do that, we’ve used the react-window library. We’ve also learned how to integrate it with react-virtualized-auto-sizer and react-window-infinite-loader. Thanks to that, we’ve achieved an infinitely-loading list and improved the performance measured with the Lighthouse audit.