React Array Re-render Performance

October 19, 2017 0 Comments

React Array Re-render Performance

 

 

Using React.PureComponent can save you up to 30% time spent in JS if you are often re-rendering arrays where only some items actually change (compared to using Functional components or React.Component).

Using React.PureComponent can save you up to 30%

Check it out yourself on react-array-perf.now.sh.

You can stop reading here if you are not dealing with frequent updates of arrays where actually only some items change at a time. Some real life examples of updating only a some items are based on:

  1. User input affecting the array (e.g. toggling a “star” button)
  2. Periodic / frequent polling (e.g. stock data dashboard)
  3. Push updates (e.g. scoreboard)

The smaller the ratio changedItems.length/array.length the more benefit you can get from using React.PureComponent.

When writing “modern” (as of 2017) Javascript with React many people use functional approaches to state management, like redux.

…all elements are considered for reconciliation…

Reducers should treat the input state as immutable and should return a new array when one or more items must be changed due to some action being dispatched:

const users = (state, action) => {
if (action.type = 'CHANGEUSER1') {
return [action.payload, ...state.slice(1)]
}
return state
}

Let’s assume that all users in the array are rendered by this component:

import User from './User'
const Users = ({users}) =>
<div>
{
users.map(user => <User {...user} />
}
</div>

The point here is: Whenever users prop changes, all elements are considered for reconciliation. Even if only one element actually needs to be updated.

This is where React.PureComponent can kick in. It internally keeps the state and props of the component and does a shallow comparison before doing more update work. The shallow comparison in not for free, but in this case it is more efficient.

I have set up a very ugly example which demonstrates this effect.

It renders a user list of length 200. The list re-renders 400 times and only changes the first user item of array of users.

const getUsers = () =>
Array(arraySize)
.fill(1)
.map((_, index) => ({
name: 'John Doe',
hobby: 'Painting',
age: index = 0 ? Math.random() * 100 : 50
}));

You can run the performance test here: react-array-perf.now.sh and the source is available at github.com/lipp/react-array-perf.

It is note worthy that Firefox benefits most (ca. 30%) and Safari benefits least (ca. 6%) and Chrome benefits moderate (ca. 15%).

No! PureComponents are no silver bullets for performance and there are plenty of reasons to favour Functional components or React.Component .

“Early optimization is the root of all evil” — Many people (including Scott Meyers)

This is my first post. I hope you like it in some way or find it useful.


Tag cloud