8 January, 2021Read Time 3 min read

Virtualized Lists in React

Cristina Radulescu
Written by

Cristina Radulescu Software Developer

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.

Virtualized Lists in React

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.

12345678910111213141516171819202122
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:

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

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

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

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

Virtualized Lists in React

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.

Topics
EngineeringReactReactVirtualizedListAutosizer