Optimize App Performance using React Window
Introduction
Rendering a large list of data is a common feature that you might want to implement in your web application. From achieving infinite scrolls in social media feeds to product listings on e-commerce websites, the use cases are many.
However, rendering large lists containing thousands of items in the UI can be a DOM-expensive task. It often leads to the over-allocation of DOM nodes and hence, creates performance bottlenecks. So what is the right way to do it?
Let’s talk about?virtualization?and how to efficiently render large list structures in your React app using the popular?react-window?library.
What is Virtualization?
Virtualization (or Windowing)?is a technique that helps us render large amounts of data by keeping track of the user’s scrolling position and displaying only the DOM contents that are visually relevant at that current scroll position. It aids us in displaying data in grid format or list format.
Virtualization
How does Virtualization work?
A simple implementation of a virtualized list will need us to pre-calculate the total height of our list by multiplying the dimension of the list item with the total count of the list items. We then position the list items to create a list on which the user can perform the scroll. It provides a UX similar to an infinite scroll but adds and removes the data from the long list incrementally just as the data enters the visible viewport without affecting the other items.
However, we do not need to go through all these steps since we will be using?react-window?to achieve virtualization in this tutorial.
Why do we need Virtualization?
The key reason why we need to consider virtualization while rendering large lists is simply that a large DOM size is problematic. If you have ever used?Google Lighthouse?or PageSpeed Insights, you’ve probably come across the warning “Avoid an excessive DOM size“. The Lighthouse’s DOM size audit fails if a page has:
Lighthouse audit on excessive DOM size
An excessive DOM size can impact your page performance in the following ways:
To know more on this topic, check out the following articles.
In order to optimize the DOM size of your React application, and render large tree structures while minimizing the number of nodes created, one recommended solution is to implement virtualization with the help of a windowing library like?react-window.
What are the alternatives for Virtualization?
Apart from virtualization, there are a few other ways to display a large list of data. The most common alternative options are:
Infinite Scroll vs Pagination vs Load More
For a detailed pro & con comparison between Pagination, Infinite Scrolling, and Load More and to figure out when to use which, check out this blog post –?Pagination vs. Infinite Scroll vs. Load More Explained.
Virtualization essentially provides us with all the benefits of pagination along with the UX of infinite scrolling.
What is React window?
The?react-window?is a windowing (virtualization) library that provides React components for efficiently rendering large lists and tabular data. The react-window work by rendering only a part of a large data set, just enough to fill the viewport.
Virtualize large lists with react-window
According to the?official docs, the library helps us to address the following common performance bottlenecks:
The?react-window?is a complete rewrite of the?react-virtualized?library, both authored by?Brian Vaughn, who is also a member of the React core team. The author says that react-window is lighter, faster, and beginner-friendly compared to react-virtualized which has, apparently, more features.?Windowing wars: React-virtualized vs. React-window?is a well-explained article that compares the 2 windowing libraries and helps you decide which is right for your project.
Do you know that react-window has over 1,527,307 weekly NPM downloads and 13.4k+ Github stars?
The below graph shows the NPM download trend comparison between react window and react virtualized.
NPM Download Trends: react-window vs react-virtualized
What are the React-window React components?
As mentioned, React window helps us to display data in list and grid format. For this, it out-of-the-box provides us with four components:
In the upcoming sections, we will learn how to utilize these components to achieve virtualization through working demos.
Getting started with Basic React Project Setup
Step 1:?Let us start with the basic React project setup using?CRA.
Step 2:?Navigate to the project folder once the app is created successfully. Then…
Step 3:?Install the dependencies. We will use the?faker?library to generate the large list of data.
Step 4:?Run the application.
The app starts running and is served at?https://localhost:3000/.
Creating and Rendering a large list without Virtualization
Now that our React app is running, next, let us create a large list and render it. The steps are as below.
Step 1:?Inside the?App.js?file, let us generate a large list of dummy user data using the faker library and initialize our data state by the?useStatehook lazy loading.In this code, I am creating an array with a length of 1000.
Step 2:?Now we need to render the list. Inside?src/components?let us create two components named?List?and?ListItems.
The List component accepts an array of?userData?as a prop. It then iterates through it and renders a list by passing each array item to the ListItem component as a prop.
Step 3:?Inside the?App.js?let us render the List component.
Our final code for App.js looks like this.
Step 4:?Replace the CSS style inside?App.css?with the below.
Step 5:?Run the code. Our app looks as below.
Now, if we observe the DOM, we can see that all the 1000 list items are rendered in the DOM on the initial load itself, creating large tree structures.
[Demo] How to virtualize a large list using React Window?
In this section, let us learn how to implement virtualization on a list using?react-window?step by step. We will be covering two scenarios:
How to virtualize a fixed-size list?
If you want to render a long one-dimensional list of equally sized items, you can make use of the?FixedSizeList?component provided by React window.
A function that renders the rows is passed as a child to FixedSizeList. The children component exposes a few props:
A few mandatory props that you need to pass to the FixedSizeList are:
Check out the docs?here?to get the complete list of all props and methods supported by the FixedSizeList component.
Now, let us move on to the implementation. I will be demonstrating how to achieve virtualization on the list that we created in the previous section.
Step 1:?Create a new component called?FixedSizeList.js?(any name can be given).
Inside this component, we will import the?FixedSizeList?component of React window and pass all the props and define the children component using?ListItem.
Code Explanation:
Also, update the ListItem component to receive the style parameter as shown below:
Step 2:?In , let us call our FixedSizeList component to render the list.
Our final code for App.js looks like this.
领英推荐
Step 3:?Run the code. Our app looks as below.
Rendering a fixed-size list with virtualization
Now let us observe the DOM again. We can see that only a few items are loaded in the DOM and as we scroll, the items are updated.
Rendering a fixed-size list with virtualization
We have successfully implemented virtualization on a Fixed sized list!
How to virtualize a variable size list?
If you want to render a list of items having different sizes, you can make use of the?VariableSizeList?component provided by React window. The VariableSizeList component works in the same way as FixedSizeList but with the following additions in props.
Also here,?itemSize?is expected to be a function instead of a specific value. For eg:
Check out the docs?here?to get the complete list of all props and methods supported by the VariableSizeList component.
Let’s move on to implementation now.
Step 1:?Create a new component called?VariableSizeList.js?(any name can be given).
Inside this component, we will import the?VariableSizeList?component of React window and pass all the props and define the children component using?ListItem?as we did in the previous example.
For this demo, to generate the rows having variable heights, I am writing an arbitrary function called?itemSize?which will assign a row height value of 50px to all even rows and 25px to all odd rows. Note that, your row heights/column widths (for vertical and horizontal layouts respectively) should be based on your actual content.
Finally, I am assigning the itemSize prop of the List with the itemSize function.
Step 2:?In?App.js, now let us call our FixedSizeList component to render the list.
Our final code for App.js looks like this.
Step 3:?Run the code. Our app looks as below.
Rendering a variable-size list with virtualization
We have successfully implemented virtualization on a Variable sized list!
[Demo] How to virtualize a grid using React Window?
Using react-window we can also virtualize a multi-dimensional list or grid. Here, the visible content window changes as the user scroll vertically and horizontally.
Moving window of content in a virtualized grid is two-dimensional
In this section let us learn how to implement virtualization on a grid using?react-window?step by step. We will be covering two scenarios:
How to virtualize a fixed-size grid?
If you want to render a large grid of equally sized items (or cells), you can make use of the?FixedSizeGrid?component provided by React window.
The FixedSizeGrid API is similar to FixedSizeList, but now you need to pass height, width, and item count for both rows and columns. Also, the children component exposes?rowIndex?and?columnIndex?props for rendering individual cells.
With that said, let us move on to the implementation.
Step 1:?First of all, let us create a multi-dimensional array of user data for feeding our grid. I am modifying, my data state initialization in App.js as below.
This code will create a multi-dimensional array of 100 rows and 10 columns.
Step 2:?Now we need to render the grid. Inside?src/components?let us create two components named FixedSizeGrid and GridItem.
Step 3:?Inside the?App.js?let us import and render the grid component.
Our final code for App.js looks like this.
Step 4:?Run the code. Our app looks as below.
Rendering a fixed-size grid with virtualization
We have successfully implemented virtualization on a Fixed sized Grid!
How to virtualize a variable-size grid?
Likewise, to virtualize a grid having varying cell sizes, you can make use of?VariableSizeGrid?component. The component has the same props as FixedSizeGrid, but, for changing column width and row height values, you will need to pass functions to their respective prop.
Let us move on to implementation.
Step 1:?Create a new component called?VariableSizeGrid.js?(any name can be given).
Inside this component, we will import the?VariableSizeGrid?component of React window and pass all the props and define the children component using?GridItem?as we did in the previous example.
For this demo, to generate the rows and columns having variable width and height values respectively, I am writing two arbitrary functions called?columnWidth?and?rowHeight?and passing the values to props.Note that, your row heights/column widths should be based on your actual content.
Step 2:?In App.js, now let us call our VariableSizeGrid component to render the list.
Our final code for App.js looks like this.
Step 3:?Run the code. Our app looks as below. I have added a border style to distinguish the cells.
Rendering a variable-size grid with virtualization
We have successfully implemented virtualization on a Variable sized grid!
[Demo] How to implement scrolling indicators
As an additional performance optimization, while expensive elements are being loaded you might often want to show a simple UI like loaders or skeletons on scrolling. In this section, let us learn how to implement a scrolling indicator on a react virtualized list.
Step 1:?Enable the?useIsScrolling?property for your react-window list component.
Step 2:?Now, expose the?isScrolling?prop (boolean value) to the children component. When the isScrolling value is true, render your loaders and when false, load your list items conditionally.
Our final code is as below.
Step 3:?Run the code. Our app looks as below on scrolling now.
Rendering virtualized list with scroll indicators
Additional Features
In this section, let us briefly touch upon other cool features supported by React window.
What are the alternatives for React window?
A few other related libraries that can help you implement virtualization in your React app are:
For a quick comparison, you can check out the stats below.
NPM download comparison
Wrapping Up
Virtualization or Windowing helps address performance bottlenecks caused by DOM element over-allocation while rendering large lists in the UI. However, implementing it without any library support can be pretty painful.
In this blog post, we learned react-window usage in various scenarios, and also we discussed additional features supported by the library. Hoping you found this tutorial helpful! All the source codes are available in this?GitHub repo.
I also strongly recommend you check out the following resources to dive more deeply into the topic.
More Interesting Reads From Our Blogs
Easily Convert Figma Design to Code
Do you want to be 2x faster in developing your UI code?
The good news is you can easily convert your Figma design into production-friendly React code in no time! Check out?CopyCat, an AI-powered plugin that will empower you by converting your Figma design to UI code. Copycat also provides seamless support to leading UI frameworks including?Bootstrap,?Tailwind CSS, and?Material UI. Start building world-class UI in half the time using Copycat now!
Original article: https://www.copycat.dev/blog/react-window/
You can see the original article here: https://www.copycat.dev/blog/react-window/
Helping Ecommerce shops get the most out of their Online Ad Spends | SWE @ Mable | Proficient in Rust, Golang, Python, TypeScript
2 年DOMinate away!