Case StudyFront End

Virtualization is a performance optimization technique that enhances the rendering of long lists in web and mobile applications by rendering only the visible items on the screen and dynamically adjusting content.

Irshadi Bagasputro

05 March 2023 · 5 min read

Optimize List Performance with Virtualization

What is List Virtualization ?

There may be times where we need to display a large list or large table that contains many columns or many rows – sometimes, even both. Loading every single item on such a list can affect performance significantly. Enter virtualized list —or also know as “windowing”, which was a concept of only rendering what is visible to users. This concepts solve the performance problems of rendering large list or table.

How does List Virtualization Works ?

virtualized-list-concept.gif

virtualized-list-concept.gif

"Virtualizing" a list of items involves maintaining a window and moving that window around your list. The number of elements that are rendered at first is a very small subset of the entire list and the "window" of visible content moves when the user continues to scroll. Let’s put it this way: Imagine you have 1000 list of elements, rather than rendering 1000 of elements — which can affects performance, because on slower initial rendering or scroll performance. Instead, You only render 5 elements that visible to the user. By implementing virtualized list, it would benefit the low-end devices. You can display more items as the user scrolls, replacing the previous list element with the new one.

How to implement List Virtualization ?

There’s several library out there that provides this function. But my top two is by Brian Vaughn, react-virtualized and react-window. Personally, I would prefer react-window over the other just because it’s much smaller and faster. Here’s the comparison:

react-window_bundlesize.png

react-window_bundlesize.png

react-virtualized_bundlesize.png

react-virtualized_bundlesize.png

The API’s for both package are relatively similar, but in this case I will use react-window.

List Virtualization Implementation

list-virtualization.png

list-virtualization.png

Lists render a windowed list (row) of elements meaning that only the visible rows are displayed to users (e.g FixedSizeListVariableSizeList). Lists use a Grid (internally) to render rows, relaying props to that inner Grid.

Rendering a List of Data using React

There’s 99% chance that you already know how to render list data in React. But for a moment let’s assume that you don’t. Imagine we want to render a list of people, in a scroll-able div container. Given a set of data that looks like this:

1

const people = [

2

{

3

name: "Aditya Kurnia Harapan",

4

age: 27

5

},

6

{

7

name: "Azhari Rizkita Priyono",

8

age: 24

9

},

10

//...some other people here

11

// and then comes my name

12

{

13

name: "Irshadi Bagasputro",

14

age: 27

15

}

16

// ...and many more

17

];

In a traditional—React way, we need to do something like this, basically we iterate the whole array/list with a .map function. And it will returns the JSX itselfs.

1

const PeopleList = () => {

2

return (

3

<div>

4

{people.map(({ name }) => (

5

<Item>{name}</Item>

6

))}

7

</div>

8

);

9

};

Usually, there won’t be a problem using this traditional approach, but here’s the interesting part. Image the people array on the example above, contains a billion of people. What react did is it will iterate, through every item on the list and it will paint it to the DOM. This is painful and expensive things that react can do. The longer the list, the more of user’s device performance used.

Rendering a Virtualized List of Data using React

One way to prevent this is by using Virtualization Windowed List, instead of iterating through every item on the people array, it will only render several item inside people array. Virtualization achieve this by lazily paint the item to the DOM as user’s scroll through the scroll-able container. With the same set of data, now let’s refactor those code using react-virtualized .

1

import { List } from "react-virtualized";

2

3

const PeopleList = () => {

4

const ref = React.useRef();

5

6

// More: https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md#rowrenderer

7

const rowRenderer = ({ index }) => <Item>{people[index].name}</Item>;

8

9

return (

10

<List

11

ref={ref}

12

height={600}

13

width={300}

14

rowCount={people.length}

15

rowHeight={40}

16

rowRenderer={rowRenderer}

17

overscanRowCount={1}

18

/>

19

);

20

};

Let's dive into the code snippet above, and at first glance, we notice that the only missing piece is the looping process, which is expertly handled by the <List /> component. However, there are a few other mandatory props that we must address, including height, width, rowCount, rowHeight, and rowRenderer.

Starting with the rowRenderer prop, it plays a crucial role in rendering a single row or item, determined by its index in the list. This specialized function allows the item to be virtualized intelligently based on the window or box scanner, optimizing performance by rendering only the visible items on the screen.

The significance of height and width cannot be overlooked; they define the dimensions of the virtualized window that contains multiple rows. By setting appropriate height and width, we establish the boundaries within which rows will be efficiently virtualized, ensuring a smooth and seamless user experience, regardless of the size of the underlying data.

rowHeight is another vital prop, which can be either a function or a number. It comes into play during the scanning process, helping to determine the size of rows within the virtualized window. This information is crucial for the intelligent rendering of rows as the user scrolls through the list.

Lastly, let's talk about the rowCount prop. It holds paramount importance in predicting and determining the total height of the list. The calculated total height is derived from the simple formula rowCount * rowHeight, and this value aids in detecting the scroll.x position based on the window scroller.

By leveraging these essential props in tandem with the <List /> component, we harness the power of virtualization, allowing us to efficiently handle and display large datasets while maintaining an optimal user experience. The combination of rowRenderer, height, width, rowHeight, and rowCount culminates in a responsive and high-performing list that dynamically adapts to user interactions.

Grid Virtualization Implementation

grid-virtualization.png

grid-virtualization.png

Grid renders tabular data with virtualization along the X-Axis and Y-Axis — this means it has both vertical and horizontal virtualization support. (e.g FixedSizeGrid and VariableSizeGrid). It only renders the Grid cells needed to fill itself based on current horizontal/vertical scroll positions.

Rendering Grid of Data using React

The next time, I will give an example for Virtualized Grid.


In summary, virtualized lists are a powerful optimization technique that improves the rendering performance of long lists in web and mobile applications by rendering only the visible items on the screen, dynamically adjusting the list content as the user scrolls. This results in a smoother user experience, especially when dealing with large datasets.


© 2023 irshadibagas.com