Why Did You Render Mr. Big Pure React Component?

Tracking unnecessary React component re-renders using the @welldone-software/why-did-you-render library

Vitali Zaidman
Welldone Software

--

Sometimes you know a certain React component should not be re-rendered unless there’s a very good reason. But how can you enforce it?

In this image we can see how the library notifies about an unnecessary update of BigListPureComponent.

Looks like an always-new style object was passed to the component:

Notice how {width: ‘100%’} is recreated on every render thus it is different on every render.

And caused the whole list to re-render on every rendering of it’s father (in this case, when “increase” is clicked). Even if none of the other props changed. Not the items, not the loading- none.

>> HERE << is a sandbox to test it.

In part 2 of this article we explain about more of these cases.

And it’s Even Worse

Since the component is a pure component, it constantly compares all it’s props to decide if shouldComponentUpdate, and this is costly too.

But… the return value from this costly calculation is always true because:
prevProps.style !== nextProps.style

Always. Oops…

The Solution in This Case

The style object creation should move out of the render functions, for example like this:

const bigListStyle = {width: '100%'}
const Main = () => (
....
<BigListPureComponent style={bigListStyle} {...manyOtherProps}/>
)

Then it would not re-render when Main re-renders.

Oops

The lesson from this example is that we need a way to ensure big components are not re-rendered when they are not supposed to.

Obviously, this is just a simple example. Sometimes these re-renders are caused by much more complex scenarios which are even harder to notice.

Remember: You develop on a very strong computer so you would probably not notice performance issues when developing. Your customers, on the other hand, would not miss them. If you want your users to have the best experience, you must find a way to monitor and fix these issues.

Why Did You Render

And here we get to the @welldone-software/why-did-you-render library.

By launching it in your app initialization and adding a whyDidYouRender static to the components you want to track, like this:

class BigListPureComponent extends React.PureComponent {static whyDidYouRender = true// a lot of logic and handlers
render(){
return (
// a list of 1000000000000 entries
)
}
}

You will receive notification in the console if anything goes wrong:

If you don’t want to “pollute” your code, you can also track components by their name using the include option:

whyDidYouUpdate(React, {include: [/pure/]})

In this example we track all pure components from the recompose library that changes the name of components to be pure(YourComponent).

Reporting

You can change the way unnecessary renders are reported to report them to an object, remote log or to write them into a file.

Enforcing

If you are concerned about missing these console logs, you can also use this library in your tests. The library perfectly works with enzyme and react-test-renderer, and as mentioned above you can report to an object in your tests to ensure nothing was re-rendered.

Chrome is Great

Chrome lets you save objects from the console as globals so you can easily access them in the console command line:

Click here to read part 2 of this article where we explain about common fixing scenarios.

Enjoy Tracking Updates :D

--

--