Photo by Chris Liverani on Unsplash

Improve your React app performance using React Profiler

Laure Retru-Chavastel
inato
Published in
4 min readMay 2, 2022

--

Recently, I was trying to improve the performance of a page in our React app, and I quickly suspected unnecessary re-renders to be the main issue there. After some investigations, I stumbled upon the React DevTools profiler plugin:

This plugin uses React’s experimental Profiler API to collect timing information about each component that’s rendered in order to identify performance bottlenecks in React applications. (source)

More particularly, I discovered a kind of hidden option of this plugin: being able to know why a component rendered. I found this feature so useful that I decided to create this article to share how to use it!

Prerequisites:

  • Use React ≥ 16.5 in DEV mode
  • Have React DevTools as an extension for your browser (Chrome or Firefox)

Improve a basic app with React Profiler

First of all, here is how to enable this option in your DevTools:

Now, let’s take the example of this simple application where you can see your goals of the day and set them as done. Let’s use React profiler to generate a profile and check what happens in our application after we click on the “Set as done” button.

“The color of a bar indicates how long the component (and its children) took to render in the selected commit. Yellow components took more time, blue components took less time, and gray components did not render at all during this commit.” (source)

We can see that all the “Goal” sub-components were re-rendered. Ideally, as we only updated the Goal “Read 30 min” we would expect that only this Goal component would be re-rendered, not the other Goal components.

How can we fix this? Now is the time to take advantage of the option we selected earlier to know why a component rendered! Let’s hover the first Goal component in the profiling data:

So the cause is that the property setAsDone has changed. Let’s fix this quickly:

Thanks to that change, the method setAsDone won’t change at each render of the Goals component. Unfortunately, that won’t be enough here to prevent the re-render of the other Goal components. Here is what the profiling data tell us now:

So Goal components re-rendered because Goals component re-rendered. And Goals component re-rendered because “Hook 1 changed”, which is not very explicit right?

To know what this “Hook 1” is, let’s switch to the “Components” tab and the DevTools will smartly show you the right component:

We can now see that "Hook 1 changed” actually means "the state goalsReached changed” which is indeed the case as we added the goal “Read 30 min” in this state.

In this specific case, we could use React.memo to fix our issue (it might not be the best solution in every case of course, but let’s keep things simple for this example).

“If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.” (source)

Let’s profile our app one more time:

We can now see that only the right Goal component was re-rendered, while the others were not 🥳

That should help you in some of your investigations to improve the performance of your React app! Feel free to ask your questions or share your experience and tips with React Profiler in the comments!

--

--