In this React performance optimization tutorial, you will learn about Reactâs shouldComponentUpdate lifecycle method and Reactâs PureComponent API to a prevent rerender for React components. Usually React components and their child components rerender if state or props change. However, by using Reactâs API, you can step in and make the decision when to rerender a component. You can find the finished application in this GitHub repository .
Before learning about Reactâs API for perf optimizations, letâs come up with a scenario that enables us to apply Reactâs shouldComponentUpdate and PureComponent. In the following, you will be rendering a large list of items. After experiencing the rerendering of the list of items as performance problem, we will go through different performance optimization solutions. Your initial application will be the following:
If you have not styled-components installed yet, you can add it as library via npm with npm install styled-components . Otherwise, as you can see, the application generates a list of numbers once and renders them as a list of items. Each item is the square of its number which is passed as prop to the Square component.
In the next step, letâs add an interactive element to our application. Next to the list of squares, there should be a button to toggle the perspective of the list.
The local state of the App component changes when the button is clicked, but the local state itself isnât used yet. In the last step, you are using a styled component with a conditional to toggle the perspective by applying a flexbox style.
Now you should be able to toggle the perspective (rows, columns) of the list of items by clicking the button. Depending on the number of items you are generating for your list once your application starts, the toggling of the perspective takes some time, because with every state change all your components rerender. You can confirm it by adding console logs to your App componentâs child components and the App component itself.
As you can see by looking at the console logs after clicking the button, every child did update and rerender. This leads to a performance problem, because all Square components are rerendered too. In the next sections, we are going through a couple of solutions on how you can prevent a child component from rendering in React. Itâs not necessary to have a child rerender when none of its relevant props are changing. However, all Square components are rerendered even though only the perspective changes which is only used in the Perspective component.
The first solution used to prevent a component from rendering in React is called shouldComponentUpdate. It is a lifecycle method which is available on React class components . Instead of having Square as a functional stateless component as before:
You can use a class component with a componentShouldUpdate method:
As you can see, the shouldComponentUpdate class method has access to the next props and state before running the re-rendering of a component. Thatâs where you can decide to prevent the re-render by returning false from this method. If you return true, the component re-renders.
In this case, if the incoming number prop didnât change, the component should not update. Try it yourself by adding console logs again to your components. The Square component shouldnât rerender when the perspective changes. Thatâs a huge performance boost for your React application, because all your child components donât rerender with every rerender of their parent component. Finally, itâs up to you to prevent a rerender of a component.
In the previous case, you have used shouldComponentUpdate to prevent a rerender of the child component. It can be used to prevent component renderings on a fine-grained level: You can apply equality checks for different props and state, but also use it for other kind of checks. However, imagine you are not interested in checking each incoming prop by itself, which can be error prone too, but only in preventing a rerendering when nothing relevant (props, state) has changed for the component. Thatâs where you can use the more broad yet simpler solution for preventing the rerender: Reactâs PureComponent .
Reactâs PureComponent does a shallow compare on the componentâs props and state. If nothing has changed, it prevents the rerender of the component. If something has changed, it rerenders the component.
As alternative, if you want to use a functional stateless component as PureComponent instead, use recomposeâs pure higher-order component . You can install recompose on the command line via npm with npm install recompose . Then apply its higher-order component on your initially implemented Square component:
Under the hood, recompose applies Reactâs PureComponent for you. Again I encourage you to add console logs to your components to experience the rerenders of each component.
This small yet powerfull React performance optimization tutorial has shown you examples for Reactâs shouldComponentUpdate() and Reactâs PureComponent. As you have seen, you can also use higher-order components that implement these performance optimizations for you. You can find the finished application in this GitHub repository .
After all, you can always use console log statements to track your component rerenders. If shouldComponentUpdate is not called, check whether the props or state have changed in the first place, because this is a major source of this lifecycle method not being called. On the other hand, you should use these performance optimizations in React carefully, because preventing accidentally a rerendering may lead to unexpected bugs. Because of its virtual DOM, React by itself is a performant library, and you can rely on this fact until something becomes a performance bottleneck in your component hierarchy. Itâs usually the case when rendering a large list of data. Then itâs recommended to check the internal implementation for the component of an item in a list. Maybe before using shouldComponentUpdate or PureComponent, you should change the implementation of the component in the first place.