Gatsby Theme Starter

ProfileArticles

React Performance — Code Changes(Part-I)

August 2nd, 2019

There are many ways to improve React application performance by making small changes to your code and tweaking around configuration files.

We will be covering improvement in performance by few changes to your code.

Let's go into the topic.

1. Pure Functional Component

React.memo() is introduced in version 16.6.0 which compares its properties to its previous values before rendering. If both previous and present properties are same, comparison with virtual dom is also altered.

Let’s dive into real application example:

In the above header, we wrapped Header.js into memo. which is used in to render in:

Render method of Index page with Header Component.(Note: Most of the code is sliced. you can find the code in here.)

Demonstration of a sample application:

With memo being used on the stateless component:

console-log-when-memo-is-used

The Console.log`Rendered!` is logged once. Irrespective of how many times the render button is clicked.

When a component is not wrapped inside a memo():

console-when-memo-is-not-used

Clicking `Render List` multiple times without using memo(). re-rendered the component again and again.

Pitfall:

Do not use memo() on components that change frequently.

Ex: Single ListView Component for an Index page.

Do not add memo() to components like above one. As the properties passed change on every iteration.

React.memo() allows the second argument to add custom comparison function.

function MyComponent(props) { /* render using props */ } function areEqual(prevProps, nextProps) { /* return true if passing nextProps to render would return the same result as passing prevProps to render, otherwise return false */ } export default React.memo(MyComponent, areEqual); // Courtesy to React Documentation

Note: React.memo does the only shallow comparison on the complex props objects.


2. Stateful Pure Component:

How is the performance improved with a PureComponent?

Instead of checking virtual DOM node changes with previous virtual DOM. we check the objects before comparing between virtual DOMs. If the objects are the same no comparison between virtual DOMs are done.

Using pure component is a great way to avoid unnecessary re-renders wherever complex objects are not passed as props and were not added as a local state of a component.

Ex: on an input form.

PureComponent Demo

In the pen attached. Both the child components EmployeStatus and TextInput are PureComponent and console.log is added to check whether the component is re-rendered. Without both being a PureComponent the input change in TextInput will also update the EmployeStatus component as well.

Custom comparators can be added on normal components by implementing shouldComponentUpdate by yourself. It allows two arguments nextProps and nextState.

Note: Do not add shouldComponentUpdate where data to component changes frequently.


3. React Profiler

Resolving issue involves finding a point from where the issue is propagated.

You can benchmark the rendering components using React Profiler and find potential bottlenecks in your code. Finally, make an action plan to resolve it.

To evaluate our performance degradations, we will be using React Profiler API which is added in version 16.5 that is supported by React Dev Tools Profiler Plugin. Disable all the other extensions as they can skew our results.

You can find the profiler tab on your chrome extension here.

Profiler In a Chrome Browser

React has two phases:

  1. Render phase: This phase calls the render() method and compares the previous virtual dom for any changes before committing.

2. Commit phase: This phase applies the changes to the DOM.

You can find from the screenshot that divides the component render times stacked above each other. And data inside the component can also be found on selecting the component in the profiler.

Conclusion:

  • Use React.memo() where re-rendering of a functional component is redundant when props object passed has no changes.

  • Use PureComponent when no re-painting of DOM redundant on props and internal state object is unchanged.

  • Both the above statements are true for only when simple objects are used on props and internal states. Custom comparators for React.memo() and shouldComponentUpdate Lifecycle with deep object comparison should be used.

Coming Soon: React Performance-Configuration Changes(Part-2)

Find the application we will be using for this post here.

ashr81/react-perfopt Evaluates React.memo() and Pure Component.github.com

After all my first article, thanks medium for the opportunity. Hope this helps others. Happy Coding Everyone :)