React Faster Performance: Highlighting React Components Updates

Chidume Nnamdi 🔥💻🎵🎮
Dev Proto
Published in
6 min readJul 30, 2020

Problems we commonly face when using React is the case of wasted renders. To conquer these problems, we need sophisticated tools to enable us to knife through these problems to see why and how they occur.

React Developer Tools provides just that. In this post, we will learn how we can leverage React Developer Tools to yet another good cause. But, first, we have to know what a wasted render is.

Check out this new REST/GraphQL testing tool:

Wasted renders

Wasted render occurs when a component is re-rendered for no apparent reason.

Why is that?

All Components in React have an internal state and properties called props they maintain. Now, when either of these changes. Common sense tells us that the Component(s) should be re-rendered so the new states and props will reflect in the DOM.

If none of the state and props values have been, also common sense tells us that there is no need to re-render the component since neither the state nor the props values have changed.

Now, when a Component is rendered when the state and the props have not changed, this is deemed to be a wasteful rendering. Our app might suffer from performance slowdowns.

Though, it will be inconsequential when the Component sub-tree is about 5~10 components. But looking at the sub-tree at the scale of hundreds or thousands components, that is when the performance will really be felt.

See this example

class Count extends Component {
constructor() {
this.state = {
count: 0
}
}
render() {
return (
<div>
<div>Count: {this.state.count}</div>
<button onClick={() => this.setState({count: this.state.count + 1})}>Incr</button>
<button onClick={() => this.setState({count: this.state.count})}>No Incr</button>
</div>
)
}
}

We have a Component that manages a local count state. We have two buttons Incr and No Incr. Each button has a click handler function, the function updates the state count using the setState method.

Components rendering is mainly caused by the setState method.

Incr button increases the count state by one. No Incr sets the state though to the current state value.

Each would cause a re-rendering when clicked in the Count component. Incr actually increases the count state, so the Component should re-render to display the new count state.

No Incr does not change the count state, and yet the Component is re-rendered. On the initial rendering, the count state is 0, when the No Incr. is clicked the state is set to itself, that is 0, the component will re-render. This should not because the previous count state was 0 and the current count state is also 0, so there is no need for the component re-rendering.

To verify this, let’s add a log message on the componentDidUpdate and componentWillUpdate lifecycle hook.

class Count extends Component {
constructor() {
this.state = {
count: 0
}
}
componentWillUpdate(nextProps, nextState){
console.log('componentWillUpdate')
}

componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate')
}
render() {
return (
<div>
<div>Count: {this.state.count}</div>
<button onClick={() => this.setState({count: this.state.count + 1})}>Incr</button>
<button onClick={() => this.setState({count: this.state.count})}>No Incr</button>
</div>
)
}
}

This will help us know when the component is updated.

Now open the Console on the DevTools. Click on the No Incr button twice. We will see two logs on our console:

componentWillUpdate componentDidUpdate

That verifies that No Incr triggers un-necessary re-renders, wasted renders.

Highlighting rendering components

React Developer Tools is a DevTool extension that helps us debug, profile and monitor our React app execution in our browser. It provides us with a highlighter that colors the boundaries of React component(s) whenever they are re-rendered.

We might not have the chance to add logs in componentDidUpdate and componentWillUpdate lifecycle methods of every component in our project to detect when an un-necessary render occurs.

React Developer Tools has a feature that can help us visualize components re-renders/update.

Install the React Developer Tools extension from here:

Now, whenever you load a React app, a React tab will appear on the DevTool:

Click on the React tab. You will see a checkbox with the label "Highlight updates". If you don't see one, click on the settings icon, a modal will pop up, there you will see a "Highlight updates" checkbox. If it is not checked, click on it to check.

Now, when a component updates, the boundaries of the component will be highlighted with a color.

There are different colors React Dev Tool can show: blue, green, yellow, red. They depend on the frequency of the components update. If a component is frequently updated, a red color highlight will be shown.

blue infrequent updates green not too infrequent yellow frequent red very frequent

Let’s see a demo:

class Count extends Component {
render() {
return (
<div className="count">Count: {this.props.count}</div>
)
}
}
class Counter extends Component {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return (
<div className="counter">
<Count count={this.state.count} />
<button onClick={() => this.setState({count: this.state.count + 1})}>Incr</button>
<button onClick={() => this.setState({count: this.state.count})}>No Incr</button>
</div>
)
}
}
class App extends React.Component {
render() {
return (
<Counter />
)
}
}
export default App

Still the same as our prev example, just that we re-factored it. A Component deals with the display of the count state, except that all is still the same.

Now, run npm run start to serve the app. Then go to localhost:3000 to load the app in your browser.

Make sure the “Highlight Updates” box is ticked.

Click on the Incr button, we see a blue color appear around the Counter and Count components.

Thes shows that Counter and Count components are updated.

Click on the No Incr button, we will see the blue color highlight the Counter and Count components. These show that both Counter and Count are updating.

Now, let’s memoize our Counter component to only update when the state and props have changed.

class Count extends React.PureComponent {
render() {
return (
<div className="count">Count: {this.props.count}</div>
)
}
}
class Counter extends React.PureComponent {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return (
<div className="counter">
<Count count={this.state.count} />
<button onClick={() => this.setState({count: this.state.count + 1})}>Incr</button>
<button onClick={() => this.setState({count: this.state.count})}>No Incr</button>
</div>
)
}
}
class App extends React.Component {
render() {
return (
<Counter />
)
}
}
export default App

Now, we memoized Counter and Count by making them extend the React.PureComponent, this feature makes the React Components only re-render when the state and props value changes.

Now, when we click on the Incr button we will see a blue color highlight, clicking on it will display blue color highlight on the Counter and Count, because the state value is changed every time it is clicked.

Now, click on the No Incr button there will be no color highlight appearing at all. This shows that no component was re-render/updated which is good because there is no need for such as no state or props were changed.

About the color types. Notice that the color highlights we saw above are all blue. It is because of how infrequent we press the buttons to re-render the components.

Now, click on the Incr button rapidly and increase it gradually, you will see the color highlight change from blue to green to yellow and finally red.

This tool just helps us easily identify which part of our app re-rendering is happening.

Conclusion

This is another tooltip for the belt.

If you have any question regarding this or anything I should add, correct or remove, feel free to comment, email or DM me

Thanks !!!

Enjoyed this article? Fill out the form below to get more of this

--

--

Chidume Nnamdi 🔥💻🎵🎮
Dev Proto

JS | Blockchain dev | Author of “Understanding JavaScript” and “Array Methods in JavaScript” - https://app.gumroad.com/chidumennamdi 📕