Since its inception, React has completely transformed the way front-end developers build web-applications. With the help of virtual DOM, React can make UI updates more efficient than ever.


This often results in making your web applications snappier. However, there’s one thing that developers often complain about React. It’s the fact that why do medium-sized React web applications perform so poorly and slowly?

The answer to this question lies in the optimization techniques for React. If you can measure and optimize how your app’s components render, you can achieve significant improvements in the overall speed of the React apps. In this article, we’ll provide you with some best optimization techniques for React. So, without further ado, let’s begin.

Usage of Pure components

A React component is said to be pure if it gives out the same output for the same props and state. For such class components, React comes with Authorization base class. The class components which extend React.PureComponent class are considered as pure components.

Pure components are the same as that of the normal components except the fact they take care of shouldComponentUpdate. It also does shallow comparisons on prop and state data.

The component is not re-rendered if the previous props and state data is the same as that of the next state or props.


React.memo for component memorization

React.memo is similar to a PureComponent except PureComponent comes from class implementation for component. On the other hand, “memo” is utilized for creating functional component. Also, React.memo is a higher-order component.

Just like in the pure components, if the input props are the same, then the component rendering will be skipped thus increasing the speed and the efficiency of the component.

This is known for boosting the application performance by memorizing output from the last execution for a few input props.

It’s also possible to pass the custom comparison logic for this component. The custom logic allows the user to look for deep comparison of objects. The component is re-rendered if the comparison function returns false, otherwise, no re-rendering of the component takes place.


The above component does the shallow comparison for both previous and the next props’ value.

Whenever we have object references that are passed as props to the memo component, there is a need for some custom login for the comparison. To get those custom logins we can pass the comparison function as the second parameter to the React.memo function.

Let’s assume props value (user) as an object reference that contains age, name,and destination of a particular user.

A deep comparison is required to be made for the above case. For this, we can create a custom function that sees for the value like age, name,and destination for the next as well as the previous props value and returns false in case they are not the same.

This is how our component won’t re-render even in the case we have reference data as input for the memo component.


The logic for comparison is provided by the code above.

The shouldComponentUpdate Life Cycle Event

The shouldcomponentupdate life cycle event is triggered before the re-rendering of the component.

This event can be effectively utilized to decide when the component should be re-rendered.

This function returns a Boolean value whenever a setState is called or there is a change in the component props. The component tends to re-render in both cases.

This function also takes the nextProps and nextState as the input and then compares it with the current state and props to decide whether there is a requirement for re-rendering or not.

Let’s understand this with an example

Suppose I want to display various employee details on the web page. Each of these employee details contains numerous properties like designation, age, name, salary, previous manager, bonus, current manager, etc.

Out of all the data, I decided to render only the age and name for a few selected employees on the webpage.

As ‘designation’ is not the part of the view, there’s no need for the view to be updated. Moreover, we can simply add custom logic in the component to check if we need the component for view update or not.

Let’s have a look at this scenario with the help of a program:


As you see that the change in the designation of the component doesn’t have any impact on the view of the application.

Whenever the setState is called, the component will try to re-render as there’s no impact of designation change to the view of the component. This is the reason why the re-rendering of component for a change of the designation will be nothing but overhead.

You can avoid this overhead with the help of a custom logic that checks if either age or name is being updated as the view is solely impacted by Age and Name.

Here shouldComponentUpdate chooses the input parameter as a new value of props and state.

Now, we can easily compare the new and current value of age and name. If we identify any change then we can trigger the re-rendering.

The passing of true from shouldComponentUpdate helps in notifying that component can be re-rendered and the vice-versa. This means that we can optimize the application component’s performance by correctly utilizing the shouldComponentUpdate.

And at last by making comparisons between the initial props and states, we can easily take decisions whether to re-render the component or not. This would result in enhanced performance of the application due to fewer re-rendering cycles.


Binding vs. Arrow Functions in Constructors

The usage of arrow functions is considered as standard practice when you work with the classes. The usage of arrow functions helps in preserving the context of the execution.

This saves us from binding the function to the context while invoking the same.


An Arrow function is of great advantage; however, it does have its share of downside as well.

When we add an arrow function, it’s added as an object instance and not a prototype property of the class. It means that reusing the components multiple times will result in multiple instances for these functions in each of the objects that are created out of the component.

Since each component has a separate instance for these functions, the re-usability is reduced. Moreover, these are object property and not the prototype property. In addition, these functions are unavailable in the inheritance chain.

These factors show us that arrow functions do have some cons. The best possible way to implement these functions is by having function binding in the constructor as mentioned above.

Refrain from using Inline style attribute

The browser usually spends a huge amount of time in scripting and rendering with the inline style.

The scripting consumes a lot of time as it has to map all the style rules that are passed to the actual CSS properties. This results in increased rendering time for the component.


In the above component, we can see the inline styles that are attached to the component. The added inline style is actually a JavaScript object rather than a style lag.

The style backgroundColor has to be converted into a CSS style property, only then the style will be applied. To achieve this, scripting and performing JavaScript execution is required. The better alternative is to simply import the CSS file into the component.

Avoid extra tags by using React fragments

A number of extra tags can be reduced by using fragments that are only required for having a common parent in the React component.

In a case when a user is creating a new component, then all the components mist only have a single parent tag. Two tags can’t dwell at the parent level. That’s why we must have a common tag at the top.

To fulfill this requirement, we generally add an extra tag at the top of the component.

Let’s have a look at the example below:


As you can see in the above component, we need an extra tag for having a common parent for the component’s rendering.

This extra div doesn’t have any role to play apart from acting as a parent tag for the component. The only reason why it’s added is that the component can’t have two-parent tags.

Having too many tags on the top level can lead to the error below:


This is why we need to have an extra tag just as a formality that can enclose the tags present at the same level.

Moreover, a possible solution to resolve the problem is by encapsulating the elements inside a fragment.

Here the fragment doesn’t come up with any extra tag for the component; however, it still provides the parent to the adjacent tags. This is done to satisfy the condition of having single parent at the top level of component.


As you can see that in the above code, there’s no extra tag to encapsulate the tags. This is the reason for saving efforts for the renderer to render which are the extra elements in the page.


I hope this article served its purpose of guiding you with the best React performance optimization tips. If these tips are applied properly then you can achieve remarkable feats as far as the speed of the React app is concerned. To read more such insightful articles on the web and mobile application technology keep reading this space.


Shahil Modan

Technical associate with a decade of experience in web and mobile app development. Expert at designing and developing efficient and high performing web applications.

Related Post