10 Performance Optimization Techniques for React Apps
Tags: react, javascript
Published: 2020-03-12 09:56:03

---
title: 10 Performance Optimization Techniques for React Apps
published: true
description: Minimize the number of costly DOM operations required to update the React UI with these optimization techniques. 
tags: React, JavaScript
---

Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. While this will lead to a faster user interface without specifically optimizing for performance for many cases, there are ways where you can still speed up your React application. This post will go over some useful techniques you can use to improve your React code. 

## 1. Using Immutable Data Structures

Data immutability is not an architecture or design pattern, it’s an opinionated way of writing code. This forces you to think about how you structure your application data flow. In my opinion, data immutability is a practice that revolves around a strict unidirectional data flow.   

Data immutability, which comes from the functional programming world, can be applied to the design of front-end apps. It can have many benefits, such as:

* Zero side-effects; 
* Immutable data objects are simpler to create, test, and use;
* Helps prevent temporal coupling;
* Easier to track changes.

In the React landscape, we use the notion of `Component` to maintain the internal state of components, and changes to the state can cause the component to re-render.

React builds and maintains an internal representation of the rendered UI (Virtual DOM). When a component’s props or state changes, React compares the newly returned element with the previously rendered one. When the two are not equal, React will update the DOM. Therefore, we have to be careful when changing the state. 

Let’s consider a User List Component: 

```javascript
state = {
       users: []
   }

   addNewUser = () =>{
       /**
        *  OfCourse not correct way to insert
        *  new user in user list
        */
       const users = this.state.users;
       users.push({
           userName: "robin",
           email: "email@email.com"
       });
       this.setState({users: users});
   }
```

The concern here is that we are pushing new users onto the variable `users`, which is a reference to `this.state.users`. 

**Pro Tip**: React state should be treated as immutable. We should never mutate `this.state` directly, as calling `setState()` afterward may replace the mutation you made.

So what’s wrong with mutating `state` directly? Let’s say we overwrite `shouldComponentUpdate`  and are checking `nextState` against `this.state` to make sure that we only re-render components when changes happen in the state.

```javascript
 shouldComponentUpdate(nextProps, nextState) {
    if (this.state.users !== nextState.users) {
      return true;
    }
    return false;
  }
```

Even if changes happen in the user's array, React won’t re-render the UI as it’s the same reference. 

The easiest way to avoid this kind of problem is to avoid mutating props or state. So the
`addNewUser`  method could be rewritten using `concat`:

```javascript
   addNewUser = () => {
       this.setState(state => ({
         users: state.users.concat({
           timeStamp: new Date(),
           userName: "robin",
           email: "email@email.com"
         })
       }));
   };
```

For handling changes to state or props in React components, we can consider the following immutable approaches:

 - For arrays: use `[].concat` or es6 `[ ...params]` 
 - For objects: use `Object.assign({}, ...)` or es6 `{...params}`

These two methods go a long way when introducing immutability to your code base.

But it’s better to use an optimized library which provides a set of immutable data structures. Here are some of the libraries you can use: 

-  [Immutability Helper](https://github.com/kolodny/immutability-helper): This is a good library when it’s comes to mutating a data copy without changing the source.
-  [Immutable.js](https://facebook.github.io/immutable-js/): This is my favorite library as it provides a lot of persistent immutable data structures, including: [List](https://facebook.github.io/immutable-js/docs/#/List), [Stack](https://facebook.github.io/immutable-js/docs/#/Stack), [Map](https://facebook.github.io/immutable-js/docs/#/Map), [OrderedMap](https://facebook.github.io/immutable-js/docs/#/OrderedMap), [Set](https://facebook.github.io/immutable-js/docs/#/Set), [OrderedSet](https://facebook.github.io/immutable-js/docs/#/OrderedSet), and [Record](https://facebook.github.io/immutable-js/docs/#/Record).
-   [Seamless-immutable](https://github.com/rtfeldman/seamless-immutable): A library for immutable JavaScript data structures that are backward-compatible with normal arrays and objects.
- [React-copy-write](https://github.com/aweary/react-copy-write): An immutable React state management library with a simple mutable API, memoized selectors, and structural sharing.

**Pro Tip:**  React `setState` method is asynchronous. This means that rather than immediately mutating `this.state`, `setState()` creates a pending state transition. If you access `this.state` after calling this method, it would potentially return the existing value. To prevent this, use the callback function of `setState` to run code after the call is completed.

**Additional Resources:**
- [Do you really need immutable data?](https://swizec.com/blog/immutable-data/swizec/7613)
- [The State of Immutability](https://medium.com/dailyjs/the-state-of-immutability-169d2cd11310)
- [Pros and Cons of using immutability with React.js](http://reactkungfu.com/2015/08/pros-and-cons-of-using-immutability-with-react-js/)
- [Handling State in React: Four Immutable Approaches to Consider](https://medium.freecodecamp.org/handling-state-in-react-four-immutable-approaches-to-consider-d1f5c00249d5)

_The original post, **21 Performance Optimization Techniques for React Apps**, is published on the [Codementor Blog](https://www.codementor.io/blog/react-optimization-5wiwjnf9hj?utm_campaign=mkt-outreach&&utm_source=devto&utm_term=react-opt)_

## 2. Function/Stateless Components and React.PureComponent

In React, function components and `PureComponent` provide two different ways of optimizing React apps at the component level.

Function components prevent constructing class instances while reducing the overall bundle size as it minifies better than classes. 

On the other hand, in order to optimize UI updates, we can consider converting function components to a `PureComponent` class (or a class with a custom `shouldComponentUpdate` method). However, if the component doesn’t use state and other life cycle methods, the initial render time is a bit more complicated when compared to function components with potentially faster updates.

**When should we use `React.PureComponent`?**

`React.PureComponent` does a shallow comparison on state change. This means it compares values when looking at primitive data types, and compares references for objects. Due to this, we must make sure two criteria are met when using `React.PureComponent`: 

- Component State/Props is an immutable object;
- State/Props should not have a multi-level nested object. 
    
  **Pro Tip:** All child components of `React.PureComponent` should also be a Pure or functional component.

## 3. Multiple Chunk Files

Your application always begins with a few components. You start adding new features and dependencies, and before you know it, you end up with a huge production file.

You can consider having two separate files by separating your vendor, or third-party library code from your application code by taking advantage of [CommonsChunkPlugin](https://webpack.js.org/plugins/commons-chunk-plugin/) for webpack. You’ll end up with `vendor.bundle.js` and `app.bundle.js`. By splitting your files, your browser caches less frequently and parallel downloads resources to reduce load time wait.

**Note:** If you are using the latest version of webpack, you can also consider [SplitChunksPlugin](https://webpack.js.org/plugins/split-chunks-plugin/)

## 4.Using Production Mode Flag in Webpack

If you are using `webpack 4` as a module bundler for your app, you can consider setting the mode option to **production**. This basically tells webpack to use the built-in optimization:

```javascript
    module.exports = {
      mode: 'production'
    };
```

Alternatively, you can pass it as a CLI argument:

```javascript
webpack --mode=production
```
Doing this will limit optimizations, such as minification or removing development-only code, to libraries. It will not expose source code, file paths, and [many more](https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a).

##  5.Dependency optimization

When considering optimizing the application bundle size, it’s worth checking how much code you are actually utilizing from dependencies. For example, you could be using `Moment.js` which includes localized files for multi-language support. If you don’t need to support multiple languages, then you can consider using [moment-locales-webpack-plugin](https://www.npmjs.com/package/moment-locales-webpack-plugin) to remove unused locales for your final bundle. 

Another example is `loadash`. Let’s say you are only using 20 of the 100+ methods, then having all the extra methods in your final bundle is not optimal. So for this, you can use [lodash-webpack-plugin](https://github.com/lodash/lodash-webpack-plugin) to remove unused functions.

Here is an extensive list of [dependencies](https://github.com/GoogleChromeLabs/webpack-libs-optimizations) which you can optimize.

## 6. Use `React.Fragments` to Avoid Additional HTML Element Wrappers

`React.fragments` lets you group a list of children without adding an extra node.

```javascript
class Comments extends React.PureComponent{
    render() {
        return (
            <React.Fragment>
                <h1>Comment Title</h1>
                <p>comments</p>
                <p>comment time</p>
            </React.Fragment>
        );
    } 
}
```

But wait! There is the alternate and more concise syntax using `React.fragments`:

```javascript
class Comments extends React.PureComponent{
    render() {
        return (
            <>
                <h1>Comment Title</h1>
                <p>comments</p>
                <p>comment time</p>
            </>
        );
    } 
}
```

## 7. Avoid Inline Function Definition in the Render Function.

Since functions are objects in JavaScript (`{} !== {}`), the inline function will always fail the prop diff when React does a diff check. Also, an arrow function will create a new instance of the function on each render if it's used in a JSX property. This might create a lot of work for the garbage collector.

```javascript
default class CommentList extends React.Component {
    state = {
        comments: [],
        selectedCommentId: null
    }

    render(){
        const { comments } = this.state;
        return (
           comments.map((comment)=>{
               return <Comment onClick={(e)=>{
                    this.setState({selectedCommentId:comment.commentId})
               }} comment={comment} key={comment.id}/>
           }) 
        )
    }
}
```

Instead of defining the inline function for props, you can define the arrow function.

```javascript
default class CommentList extends React.Component {
    state = {
        comments: [],
        selectedCommentId: null
    }

    onCommentClick = (commentId)=>{
        this.setState({selectedCommentId:commentId})
    }

    render(){
        const { comments } = this.state;
        return (
           comments.map((comment)=>{
               return <Comment onClick={this.onCommentClick} 
                comment={comment} key={comment.id}/>
           }) 
        )
    }
}
```

## 8. Throttling and Debouncing Event Action in JavaScript

Event trigger rate is the number of times an event handler invokes in a given amount of time.

In general, mouse clicks have lower event trigger rates compare to scrolling and mouseover. Higher event trigger rates can sometimes crash your application, but it can be controlled.

Let's discuss some of the techniques.

First, identify the event handler that is doing the expensive work. For example, an XHR request or DOM manipulation that performs UI updates, processes a large amount of data, or perform computation expensive tasks. In these cases, throttling and debouncing techniques can be a savior without making any changes in the event listener.

#### Throttling

In a nutshell, throttling means delaying function execution. So instead of executing the event handler/function immediately, you’ll be adding a few milliseconds of delay when an event is triggered. This can be used when implementing infinite scrolling, for example. Rather than fetching the next result set as the user is scrolling, you can delay the XHR call.

Another good example of this is Ajax-based instant search. You might not want to hit the server for every key press, so it’s better to throttle until the input field is dormant for a few milliseconds

Throttling can be implemented a number of ways. You can throttle by the number of events triggered or by the delay event handler being executed.

#### Debouncing

Unlike throttling, debouncing is a technique to prevent the event trigger from being fired too often. If you are using `lodash`, you can wrap the function you want to call in `lodash’s  debounce function`.

Here’s a demo code for searching comments:

```javascript
import debouce from 'lodash.debounce';

class SearchComments extends React.Component {
 constructor(props) {
   super(props);
   this.state = { searchQuery: “” };
 }

 setSearchQuery = debounce(e => {
   this.setState({ searchQuery: e.target.value });

   // Fire API call or Comments manipulation on client end side
 }, 1000);

 render() {
   return (
     <div>
       <h1>Search Comments</h1>
       <input type="text" onChange={this.setSearchQuery} />
     </div>
   );
 }
}
```

If you are not using `lodash`, you can use the minified debounced function to implement it in JavaScript.

```javascript
function debounce(a,b,c){var d,e;return function(){function h(){d=null,c||(e=a.apply(f,g))}var f=this,g=arguments;return clearTimeout(d),d=setTimeout(h,b),c&&!d&&(e=a.apply(f,g)),e}}
```

**Reference and Related Articles:**
["Array" Methods](https://lodash.com/docs/#debounce),
[Handling Events](https://eloquentjavascript.net/15_event.html)

## 9. Avoid using Index as Key for map

You often see indexes being used as a key when rendering a list.

```javascript
{
    comments.map((comment, index) => {
        <Comment 
            {..comment}
            key={index} />
    })
}
```

But using the key as the index can show your app incorrect data as it is being used to identify DOM elements. When you push or remove an item from the list, if the key is the same as before, React assumes that the DOM element represents the same component.

It's always advisable to use a unique property as a key, or if your data doesn't have any unique attributes, then you can think of using the `shortid module` which generates a unique key.

```javascript
import shortid from  "shortid";
{
    comments.map((comment, index) => {
        <Comment 
            {..comment}
            key={shortid.generate()} />
    })
}
```

However, if the data has a unique property, such as an ID, then it's better to use that property.

```javascript
{
    comments.map((comment, index) => {
        <Comment 
            {..comment}
            key={comment.id} />
    })
}
```

In certain cases, it's completely okay to use the index as the key, but only if below condition holds:

-   The list and items are static
-   The items in the list don't have IDs and the list is never going to be reordered or filtered
-   List is immutable
   
**References and Related Articles:**
[Consider providing a default key for dynamic children #1342](https://github.com/facebook/react/issues/1342#issuecomment-39230939),
[The importance of component keys in React.js](https://coderwall.com/p/jdybeq/the-importance-of-component-keys-in-react-js),
[Why you need keys for collections in React](https://paulgray.net/keys-in-react/)

## 10. Avoiding Props in Initial States

We often need to pass initial data with props to the React component to set the initial state value.

Let's consider this code:

```javascript
class EditPanelComponent extends Component {
    
    constructor(props){
        super(props);

        this.state ={
            isEditMode: false,
            applyCoupon: props.applyCoupon
        }
    }

    render(){
        return <div>
                    {this.state.applyCoupon && 
                    <>Enter Coupon: <Input/></>}
               </div>
    }
}
```

Everything looks good in the snippet, right?

But what happens when `props.applyCoupon` changes? Will it be reflected in the state? If the props are changed without the refreshing the component, the new prop value will never be assigned to the state’s `applyCoupon`. This is because the constructor function is only called when `EditPanelComponent` is first created.

To quote **React docs**: 

> Using props to initialize a state in constructor function often leads to duplication of “source of truth”, i.e. where the real data is. This is because constructor function is only invoked when the component is first created.

**Workaround:**

1. Don't initialize state with props which can be changed later. Instead, use props directly in the component.

```javascript
class EditPanelComponent extends Component {
    
    constructor(props){
        super(props);

        this.state ={
            isEditMode: false
        }
    }

    render(){
        return <div>{this.props.applyCoupon && 
         <>Enter Coupon:<Input/></>}</div>
    }
} 
```

2. You can use `componentWillReceiveProps` to update the state when props change.

```javascript
class EditPanelComponent extends Component {
    
    constructor(props){
        super(props);

        this.state ={
            isEditMode: false,
            applyCoupon: props.applyCoupon
        }
    }

    // reset state if the seeded prop is updated
    componentWillReceiveProps(nextProps){
        if (nextProps.applyCoupon !== this.props.applyCoupon) {
            this.setState({ applyCoupon: nextProps.applyCoupon })
        }
    }

    render(){
        return <div>{this.props.applyCoupon && 
          <>Enter Coupon: <Input/></>}</div>
    }
}
```

**References and Related Articles:**
[ReactJS: Why is passing the component initial state a prop an anti-pattern?](https://stackoverflow.com/questions/28785106/reactjs-why-is-passing-the-component-initial-state-a-prop-an-anti-pattern),
[React Anti-Patterns: Props in Initial State](https://medium.com/@justintulk/react-anti-patterns-props-in-initial-state-28687846cc2e)


## Conclusion

There are many ways to optimize a React app, for example lazy loading components, using ServiceWorkers to cache application state, considering SSR, avoiding unnecessary renders etc.. That said, before considering optimization, it’s worth understanding how React components work, understanding diffing algorithms, and how rendering works in React. These are all important concepts to take into consideration when optimizing your application.

I think optimization without measuring is almost premature, which is why I would recommend to benchmark and measure performance first. You can consider profiling and visualizing components with Chrome Timeline. This lets you see which components are unmounted, mounted, updated, and how much time they take relative to each other. It will help you to get started with your performance optimization journey.



_For more tips, head over to the [Codementor Blog](https://www.codementor.io/blog/react-optimization-5wiwjnf9hj?utm_campaign=mkt-outreach&&utm_source=devto&utm_term=react-opt) to read the original post, **21 Performance Optimization Techniques for React Apps**._