Tutorial

Getting to Grips with react-window

Published on July 22, 2019
Default avatar

By Paul Ryan

Getting to Grips with react-window

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

In the frontend development community, we tend to use the word performance quite a lot. We all have the common goal of having a performant application. Brian Vaughan developed react-window with this in mind and he did a great job of giving us a powerful tool to achieve this goal.

The Theory Behind react-window

react-window in theory is very simple to understand, the window refers to the view the user can see.

Window View

react-window will only render what the user can see, because why would we bother using resources rendering areas that the user can’t see? That would just be pure silliness!

Let’s Get Practical

Well wouldn’t it be very hard to profile an application, without an actual application? I have created an application that fetches a large list of movies, you can check out the repo here.

Just run an npm install and then npm start , you should now see the following on localhost:3000

Our App

Initial Measurements

The following code in movie-list.js will get5000 movies from our large response:

const moviesList = movies.slice(0, 5000);

We’ll use 5000 as our sample size as it’s quite chunky and will take some time to render.

We’ll start by measuring our initial performance, the first thing we’ll measure is our frame per second (FPS). To enable this in Chrome DevTools, you need to turn on rendering by clicking more tools then rendering.

FPS Meter

Our Frame Rate is at 34.0 fps which is quite slow, we are more looking for achieving something around 60fps.

Frame

The next thing we’ll measure is our First Meaningful Paint. To do this I ran a Lighthouse report, this couldn’t handle the 5000 movies so just for this test I moved the number of movies to 500

Audit

As you can see from the above, the performance is not good and remember this is with 500 movies, not 5000.

Implementing react-window

I will be making all the performance upgrades on a new branch called performance-increased, this means when you clone the repo you will have the slow application on the master branch and you can toggle between both to see the difference.

To implement react-window, you first need to install it by running npm install react-window, then import FixedSizeList.

import { FixedSizeList as List } from 'react-window';

Creating a Row

To work with the List component, we need to create a Row component like so:

// all props are passed by the List component
const Row = ({ index, style, data }) => {
  const movie = data[index];
  // style is passed by the List component to give our Row the correct dimensions
  return (
    <div style={style} key={index}>
      <Movie key={index} {...movie} />
    </div>
  );
};

We won’t go into the Movie component as it doesn’t matter, basically it’s our view for each movie.

AutoSizer Component

With our Row component created, we can then implement our List component which we wrap in an AutoSizer component:

<AutoSizer>
  {({ height, width }) => (
    <List
      className="List"
      height={height}
      itemCount={1000}
      itemSize={150}
      width={width}
      itemData={moviesList}
    >
      {Row}
    </List>
  )}
</AutoSizer>

The AutoSizer component will automatically scale our Row component’s dimensions to it’s container by passing a height and width to our List component. You can also just pass static values to the height and width prop.

To install AutoSizer, run npm install react-virtualized-auto-sizer then to import:

import AutoSizer from 'react-virtualized-auto-sizer';

List Component

The List component is quite simple, as you can see we have a prop called itemData which we pass all of our 5000 movies This allows us to access an individual movie in our Row component.

const movie = data[index];

The itemSize prop is the height of each row. The rest of the props are quite simple.

The List component passes a style and index prop to our Row component by default

Now with everything in place, let’s check out our FPS meter. This time it is much closer to our goal of 60fps.

Good Frame Rate

If you have cloned the repo and compared the two branches, you will also see just how much quicker the initial render is. To prove this, let’s run another audit.

Good Audit

Initially we scored 63 in our performance, but now we have scored 100. Our First Meaningful Paint took only 1.1s, compared to 4.8s without react-window. Also remember that this audit was ran against 5000 movies, not the 500 the initial audit was ran on.

Wrapping Up

You can see from the above just how powerful react-window is. Our application was a very simple one but we can still see great performance benefits. I hope you have learned something from this article and are closer to achieving your performance goals.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Paul Ryan

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel