Virtualized Lists in React

Cristina Radulescu
3 min readJan 8, 2021

In this article I want to describe how you can useList and Autosizer from react-virtualized. An advantage of using virtualized lists is that only visible rows are rendered into the DOM whereas the other rows are rendered only when they become visible by scrolling into the list. This could be of great help when you are working with large arrays with 1000 -10,000 records and you don’t want to keep the whole element list into the DOM, because this could lead to massive performance problems.

We will create a large set of data using faker.js that we will display. faker.js is a library that helps create random data by calling a few simple methods. The records contain information about articles having a type, title, description, image and notes.

const generateType = () => {
return Math.floor(Math.random() * 10) % 2 === 0 ? "article" : "question";
}

const generateEntry = () => {
return {
type: generateType(),
title: faker.lorem.sentence(),
description: faker.lorem.paragraph(),
image: faker.image.image(),
notes: faker.lorem.paragraph(),
}
}
export function getAllPosts(nrOfRecords) {
let allPosts = [];
while (allPosts.length < nrOfRecords) {
const entry = generateEntry();
allPosts.push(entry);
}
return allPosts;
}

In order to create an array with 1,000 elements we will call the getAllPosts method like this:

const allPosts = getAllPosts(1000);

The Autosizer will return information about height and width to the List. You need to be careful here, because in case height or width returns 0 it could be coming from one of its parents div which has a height or a width of 0 and the List will not enlarge if at least one of its parents has a height or a width of 0. You can fix this issue by setting its parents height to height: 100% or by using flex: 1 on the parent as recommended in the react-virtualized documentation which can be found here.

<AutoSizer>
{({height, width}) => (
<List
height={height}
width={width}
itemCount={allPosts.length}
rowHeight={rowHeight}
rowCount={allPosts.length}
rowRenderer={renderPost}
>
</List>
)}
</AutoSizer>

The rowRenderer property is used to render the row, whereas the rowHeight will be used to compute the height of the row in case you need different heights for a row.

const renderPost = (item) => {
const {index} = item;
return allPosts[index].type === "article" ? <ArticlePost article={allPosts[index]} item={item}/> :
<SimplePost article={allPosts[index]} item={item}></SimplePost>;
};

For the case when the item displayed is an article and not a question the height will be bigger and this can be controlled from the rowHeight property.

const EXPANDED_ROW_SIZE = 250;
const ROW_SIZE = 200;
const rowHeight = (item) => {
const {index} = item;
return allPosts[index].type === "article" ? EXPANDED_ROW_SIZE : ROW_SIZE;
};

The rendered list will look like this and you can see that the heights of the rows are different for the items depending on their type. When scrolling on the page you can notice when inspecting the elements how the elements are added and removed from the DOM.

The code source of this project can be found in github at the following repository.

I hope this article helps you get a better understanding on how virtualized lists are working and how they are helpful. Let me know what you think.

Thank you!

Special thanks to Bogdan Bucsa for his great input on virtualized lists in React.

--

--