Profiling React performance with React 16 and Chrome Devtools.
By Ben Schwarz
4 - 5 minutes
React was one of the first major front-end frameworks to not only name, but tout its rendering performance. React’s virtual dom is famous for efficiently rendering components—but what happens when those components suddenly don’t feel fast anymore? Where do you look? How do you fix it?
Today I’m going to use real React code and Chrome DevTools to demonstrate powerful new performance tracking features and how you can use them to diagnose slow rendering components.
This new performance tooling has three requirements:
Use React 16 in development mode
Export your JS with source-maps (This is optional, but highly recommended)
Use Google Chrome or Chromium’s Dev Tools (available in all current releases)
Firstly, you’re going to need some room to breathe, so go and pop Dev Tools out. Make it as large as your screen allows. “Ahh. That’s better.”
When we’re doing performance audits it’s essential that we’re working towards realistic (real world) targets. Not everyone has a $3000 computer or current model phone.
Slowing your current model Macbook by at least 4x will have it perform similarly to a Motorola Moto G4.
In development mode, as React 16 renders, it creates ‘mark and measure’ events for each component.
To create a performance profiler audit, navigate to the page that you’d like to test (on localhost) and press the ‘Start profiling and reload page’ button.
This will record a performance trace for the current page. Chrome will automatically stop recording the trace after the page has settled.
Once you’ve got a trace, your window will look something like this:
I’d like to take a second or two to point out a few things that may not be immediately obvious to someone who is new to the Performance tab.
This red bar indicator shows that there was some significant ‘CPU burn’ (long tasks) around this part of the trace timeline. We probably want to investigate there.
The colours used in the graph at the top of the performance window correspond to different types of activity. Each category has various causes, fixes, and analysis required.
Now we’re going to want to investigate that red CPU-burn area. We can see that the page rendered elements on the page during that period of the trace.
Zooming immediately displays user-timing information and a component labelled ‘Pulse’ (that takes 500ms to render).
Beneath the Pulse component, there appears to be child components rendering, although the size of those items indicates that they aren’t costing a lot of execution time.
Click the component you’d like to investigate, in this case, Pulse. This scopes the lower portion of the window to focus on only activity from the Pulse component.
Sort by total time descending. In some cases, you may want to sort by Self time, or group by something other than the URL. See what works best for what you’re investigating.
Click open the arrows until you’ve found a point in the code you’d like to investigate. In this case the map call looks suspect. It’s called a number of times and amounts to 90ms of execution time.
This is why you need sourcemaps: Clicking MetricStore.js:59 will take you to that spot in the code. Let’s go!
If you’re a little curious about what’s happening to your sites in production when they’re loaded with ads and tracking pixels and in-app chat, you can use Calibre to get a clear picture of which scripts (or services) are costing your customers time.
All major browsers support the User Timing API, but Chrome’s performance tab goes a long way further to make debugging a React application a whole lot easier.
I sincerely hope this article has helped you level up your performance auditing skills. Please leave comments to explain what you learned or of improvements you’ve been able to make on your apps. Enjoy 🙋