There will come a time when youâll work on an application that will have to display a large amount of data at the same page, the page will slow down or even the application will be blocked until the rendering is finished. Letâs see how to handle this type of situations with a virtual list.
What is a virtual list?
Virtual lists are lists that render only the visible elements inside their viewport, they allow us to efficiently render huge amounts of elements without loss of performance.
Letâs take for example Facebookâs âinfinite scrollâ, Facebook cannot render an infinite amount of posts for the user to view. It will load a certain amount of posts from the server, and then it will only render the posts that are in the viewport and a few before and after the visible posts to create the illusion of an infinite scroll.
When the user scrolls up or down a certain amount of pixels behind the scenes it will render the needed posts.
To illustrate this idea look at the following image, we have a mock Facebook feed with the users view inside the black box. When the user will scroll up or down and reach the blue area the list will know it needs to render more posts.
Thatâs how the virtual list is able to perform with huge amounts of data to display âat the same timeâ.
If we didnât use a virtual list we would have to populate the posts feed with a certain amount of posts to begin with, and they will all be rendered to the DOM. When you reach the end of the list you will have to load from the server another fixed amount of posts and render all of them to the DOM.
The following image depicts a posts feed that is rendering all of the posts loaded from the server:
This approach is far less desirable, first of all when the request returns with the data we will immediately render 50+ posts, you will see a difference in the time it takes the application to render the components to the DOM.
When you scroll you might see the scroll area judder/lag because youâve rendered a large number of components together.
When dealing with thousands of components to display you will not only render them to the DOM, you will probably need to attach certain event listeners to enable your desired behavior. Dealing with thousand of event listeners will have a big impact on your applicationâs performance.
Thatâs why a virtual list will drastically improve your performance, it will render only a certain amount of components at a time with their respective event listeners, instead of thousands at the same time.
These are all possible implications of rendering a large amount of data, some of them might not show up when the amount of data is still small, but I can guarantee it will show when you will deal with thousands of components that you need to display.
Final note, after playing around with Facebookâs âinfinite scrollâ, it seems they have mixed a virtual list with loading data from the server. When you reach the end of the scroll/list, you will see that it loads more data from the server, but the posts that have already been loaded are virtualized.
React-virtualized to the rescue
Writing a virtual list yourself might be fun as a side project but on your day to day at work you canât waste time recreating everything you need when there are good and tested libraries available.
React virtualized is a library that provides us with components that support virtualization out of the box like: List, Grid, TableâŠ
In-order to demonstrate the concept of a virtual list further Iâve used react-virtualized documentation examples.
Here we have a virtual list with 10K results, see how quick the page loads and how easy it is to scroll inside the list:
To emphasis how useful a virtual list is Iâve increased the number of rows displayed to 1 million, Iâve also enabled âshow scrollingâ at the top so we can see how the virtual list renders new data as we are scrolling. if you uncheck the âshow scrollingâ you will get a result similar to the previous image.
Iâve taken an example from react-virtualized docs for their virtual list:
REACT-VIRTUALIZED LIST CODE SAMPLE:
import React from "react";import ReactDOM from "react-dom";import { List } from "react-virtualized";// List data as an array of stringsconst list = ["Brian Vaughn",// And so on...];function rowRenderer({key, // Unique key within array of rowsindex, // Index of row within collectionisScrolling, // The List is currently being scrolledisVisible, // This row is visible within the List.style, // Style object to be applied to row (to position it)}) {return (<div key={key} style={style}>{list[index]}</div>);}// Render your listReactDOM.render(<Listwidth={300}height={300}rowCount={list.length}rowHeight={20}rowRenderer={rowRenderer}/>,document.getElementById("example"));
As you can see to use the virtual list there is not much to set up.
Import the list component.
import { List } from "react-virtualized";
Get your listâs data / fetch it from the server:
// List data as an array of stringsconst list = ["Brian Vaughn",// And so on...];
Create a function that will receive data from the list and render each row:
function rowRenderer({key, // Unique key within array of rowsindex, // Index of row within collectionisScrolling, // The List is currently being scrolledisVisible, // This row is visible within the Liststyle, // Style object to be applied to row (to position it)}) {return (<div key={key} style={style}>{list[index]}</div>);}
Render the list to the DOM, set the list height and width, add the number of rows you need to render, set each row height and add the rowRenderer function which will render each of our rows.
// Render your listReactDOM.render(<Listwidth={300}height={300}rowCount={list.length}rowHeight={20}rowRenderer={rowRenderer}/>,document.getElementById("example"));
Now that you are aware of the power that virtual lists can give you, I bet you can handle performance issues much better when it comes to large amounts of data.
I Hope you enjoyed this article and that it gave you VALUE.