- High Performance React: 3 New Tools to Speed Up Your Apps
- By Ben Edelstein
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: sunui
- Proofreader: Yzgyyang, Reid3290
React is generally fairly fast, but developers can easily make mistakes that lead to performance issues. Slow component mounts, deep component trees, and unnecessary rendering cycles can quickly combine to slow down your application.
Fortunately, there are a number of tools, some even built in React, that can help us detect performance issues. This article focuses on some tools and techniques for speeding up React usage. Each section comes with an interactive and (hopefully) fun demo!
Tool #1: Performance timeline
React 15.4.0 introduces a new performance timeline feature that shows exactly when components are mounted, updated, and unmounted. It also allows you to visually observe the component lifecycle in relation to each other.
Note: Currently, this feature is only available for Chrome, Edge, and IE, as the User Timing API it calls is not implemented in all browsers.
How to use
- Open your app and append a parameter:
react_perf
. For example,http://localhost:3000?react_perf
- Open the Chrome Developer Tools Performance bar and click Record.
- Perform the actions you want to analyze.
- Stop recording.
- Observe the visual view under the User Timing option.
Understand the output
Each color bar shows the “processing” time of a component. Because JavaScript is single-threaded, every time a component is being mounted or rendered, it hogs the main thread and blocks other code from running.
Text in parentheses like [update] describes which phase of the lifecycle is taking place. Break time axis according to the steps, you can see on the basis of the method of fine-grained timing, such as [componentDidMount] [componentWillReceiveProps] [ctor] (constructor) and render.
Stacked bars represent tree of components, and while it’s typical to have an overly deep tree of components in React, reducing the number of nested components is also helpful if you want to optimize a frequently mounted component, since each layer adds a small amount of performance and memory consumption.
Note that the timings in the timeline are built for the React development environment, which is much slower than the production environment. In fact, the performance timeline itself can slow down your application. While these times do not represent true performance metrics, the relative times between different components are accurate. And whether or not a component is fully updated does not depend on whether or not the production environment is built.
Demo #1
For fun, I intentionally wrote a TodoMVC application with serious performance issues. You can try it here.
Open Chrome Developer Tools, switch to the “Performance” bar, and click Record to start recording the timeline. Then add some TODO to the application, stop recording, and check the timeline. See if you can identify the component causing the performance problem 🙂
Tool #2: why-did-you-update
One of the biggest performance issues in React is the unnecessary render cycle. By default, React components are rerendered as soon as the parent component renders, even if their props aren’t changed.
For example, if I have a simple component that looks like this:
class DumbComponent extends Component {
render() {
return<div> {this.props.value} </div>; }}Copy the code
Its parent component looks like this:
class Parent extends Component {
render() {
return<div> <DumbComponent value={3} /> </div>; }}Copy the code
Whenever the parent renders, the DumbComponent rerenders, even though its props have not changed.
In general, if Render runs and the virtual DOM doesn’t change, and since render is supposed to be a clean method with no side effects, this is an unnecessary render cycle. Detecting this sort of thing in a large application is very difficult, but fortunately there is a tool that can help.
Use according to – did – you – update
Why-did-you-update is a React hook tool that detects potentially non-essential component rendering. It detects the component render that was called but whose props did not change.
The installation
- Install using NPM:
npm i --save-dev why-did-you-update
-
Add the following snippet anywhere in your app:
import React from ‘react’
if (process.env.NODE_ENV ! == ‘production’) { const {whyDidYouUpdate} = require(‘why-did-you-update’) whyDidYouUpdate(React) }
Note: This tool is great for local development, but be sure to disable it in production as it can slow down your application.
Understand the output
Why-did-you-update listens to your application at run time and logs out components that may have unnecessary updates. It lets you see the props comparison before and after a render cycle to determine if there might be unnecessary updates.
Demo #2
To demonstrate why-did-you-Update, I installed this library in TodoMVC and put it on the Code Sandbox website, which is an online React practice floor. Open the browser console and add some TODO to see the output.
Check out the demo here.
Note that very few components in this application have unnecessary rendering. Try implementing the techniques described above to avoid unnecessary rendering. If done correctly, why-did-you-update will not output anything on the console.
Tool #3: React Developer Tools
React Developer Tools This Chrome extension has a built-in feature for visualizing component updates. This helps prevent unnecessary rendering cycles. To use it, first make sure you have the extension installed here.
Then click the “React” TAB in Chrome Developer Tools to open the extension and check “Highlight Updates”.
Then simply manipulate your application. Interact with different components and watch DevTools work its magic.
Understand the output
React Developer Tools highlights the component being rerendered at a given point in time. Use different colors depending on the frequency of updates. Blue shows rare updates, with green and yellow transitioning to red to show frequently updated components.
Seeing yellow or red doesn’t have to be a bad thing. It can happen, unsurprisingly, by tweaking a slider or other UI elements that trigger frequent updates. But if you click a simple button and see red it probably means something is wrong. The purpose of this tool is to identify components that are undergoing unnecessary updates. As an application developer, you should have a general idea of which components should be updated at a given time.
Demo #3
To demonstrate highlighting, I purposely let the TodoMVC app update some non-essential components.
Check out the demo here.
Open the link above, then open React Developer Tools and enable update highlighting. When you enter content in the text entry box above, you will see all TODO highlighted unnecessarily. The faster you type, you’ll see the color change indicator update more and more frequently.
Fixed non-essential rendering
Once you’ve identified components in your application that don’t need to be rerendered, there are several simple ways to fix them.
Using PureComponent
In the example above, DumbComponent is a pure function that accepts only attributes. This way, the component is rerendered only when its props change. React has a special built-in component type called PureComponent that is a use case for this situation.
Instead of inheriting from react.component. react.purecomponent like this:
class DumbComponent extends PureComponent {
render() {
return<div> {this.props.value} </div>; }}Copy the code
The component will only be re-rendered if its props actually change. That’s it!
Note that PureComponent makes a shallow comparison to props, so if you use complex data structures, it may miss some property changes and not update your component.
Call shouldComponentUpdate
ShouldComponentUpdate is a component method that is called when props or state changes before render. If shouldComponentUpdate returns true, render will be called, if false nothing happens.
By executing this method, you can command React to avoid rerendering a given component without changing the props.
For example, we could call shouldComponentUpdate in the DumbComponent above.
class DumbComponent extends Component {
shouldComponentUpdate(nextProps) {
if(this.props.value ! == nextProps.value) {return true;
} else {
return false; }}render() {
return<div>foo</div>; }}Copy the code
Debug performance issues in the production environment
React Developer Tools only works with apps running on your own machine. If you’re interested in learning about the performance issues users are seeing in production, try LogRocket.
LogRocket is like a DVR for web applications, recording everything that happens on your site. You can recreate sessions with bugs or performance problems to quickly understand the root cause of the problem without having to guess why it happened.
The LogRocket tool records performance data, Redux Actions /state, logs, network requests and responses with request headers and request bodies, and browser metadata for your application. It also records HTML and CSS on a page and can recreate perfect pixel videos for even the most complex single-page applications.
LogRocket | for the JavaScript application logging and session replay tools
LogRocket helps you understand the problems affecting your users so you can go back and build great software.
logrocket.com
Thanks for reading, and hopefully these tools and techniques will help you with your next React project!
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. Android, iOS, React, front end, back end, product, design, etc. Keep an eye on the Nuggets Translation project for more quality translations.