We often encounter the need to present lists based on data. You’ve probably masturbated this code hundreds of times.

But if you need to display thousands of pieces of data at the same time, the browser will stall, lose frames, and even freeze.

This article describes how to efficiently render large data tables using React – Virtualized.

Let’s go!

First, create a React application

create-react-app virtualization
Copy the code

The app will display 1,000 comments like this:

We introduce the third-party library Lorem-IPsum to generate simulation data:

cd virtualization

npm install --save lorem-ipsum
Copy the code

Introduce rem-ipsum in SRC/app.js:

import loremIpsum from 'lorem-ipsum';
Copy the code

Next create an array of 1000 entries:

const rowCount = 1000;

class App extends Component {
  constructor() {
    super(a);this.list = Array(rowCount).fill().map((val, idx) = > {
      return {
        id: idx, 
        name: 'John Doe'.image: 'http://via.placeholder.com/40'.text: loremIpsum({
          count: 1.units: 'sentences'.sentenceLowerBound: 4.sentenceUpperBound: 8}}})); }/ /...
}
Copy the code

Each of the above data contains an ID, user name, picture, and randomly generated 4 to 8 word comments.

Use this array in render() :

render() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">Welcome to React</h1>
      </header>
      <div className="list">
        {this.list.map(this.renderRow.bind(this))}
      </div>
    </div>
  );
}
Copy the code

Add renderRow() to create columns:

renderRow(item) {
  return (
    <div key={item.id} className="row">
      <div className="image">
        <img src={item.image} alt="" />
      </div>
      <div className="content">
        <div>{item.name}</div>
        <div>{item.text}</div>
      </div>
    </div>
  );
}
Copy the code

Add styles to SRC/app.css:

.list {
  padding: 10px;
}

.row { 
  border-bottom: 1px solid #ebeced;
  text-align: left;
  margin: 5px 0;
  display: flex;
  align-items: center;
}

.image {
  margin-right: 10px;
}

.content {
  padding: 10px;
}
Copy the code

Ok, start the project YARN Start and you should see the following screen:

Looking at the element, we can see that there are quite a few divs mounted on the DOM:

Let’s measure the performance

If you’re using Chrome, just take a few steps to quickly test performance:

  • Open developer tools
  • Press Command+Shift+P (Mac) or Control+Shift+P (Windows, Linux) to open the Command menu
  • The inputrenderSelect a value from the drop-down list boxShow Rendering.
  • Click on therenderTAB,FPS MeterBefore the check.
  • Scrolling list

As you can see, the frame rate drops from 60 to about 38 as the scrollbar rolls. This is still only 1000 entries, and if you increase the number, the browser will stall or even freeze.

Then we’re going to see how We improve performance on React – Virtualized?

react-virtualizedThe principle of

Core principle: Only render what you see.

The above app renders 1000 comments, but the screen only shows you about 10, so rendering the other 990 is wasteful.

If we render only visible comments, replace the old ones with the new ones when we scroll to see more. This perfectly solves the performance bottleneck.

How do you use it?

SRC/app.js first, introduce the List component:

import { List } from "react-virtualized";
Copy the code

Replace render() with original code:

<div className="list">

  {this.list.map(this.renderRow.bind(this))}

</div>
Copy the code

Using the List component

const listHeight = 600;

const rowHeight = 50;

const rowWidth = 800;

/ /...

<div className="list">

  <List

    width={rowWidth}

    height={listHeight}

    rowHeight={rowHeight}

    rowRenderer={this.renderRow.bind(this)}

    rowCount={this.list.length} />

</div>
Copy the code

Rewrite renderRow () :

renderRow({ index, key, style }) {
  return (
    <div key={key} style={style} className="row">
      <div className="image">
        <img src={this.list[index].image} alt="" />
      </div>
      <div className="content">
        <div>{this.list[index].name}</div>
        <div>{this.list[index].text}</div>
      </div>
    </div>
  );
}
Copy the code

Start the application yarn start:

View elements:

You can see that only the visible elements are rendered.

What about performance?

Use the same method as above:

You can see it’s pretty much stuck around 60 frames. Performance bar (^_^)

This is just a simple application of React – Virtualized, just try it on!

Thanks for reading!

Esteban Herrera’s Rendering Large Lists with React Virtualized