Dev

By Carlos Santana on
Reading time: 5 minutes

performance-Zt7cB.png

NOTE: This article assumes you have some experience in React, JavaScript and Web Development topics.

This article lays out some best practices and offers tips to improve your React application performance.

Reducing the unnecessary renders by using shouldComponentUpdate

React’s default behavior is to fire the render method every time the state of the component change or when new props are received. This is the most common performance issue, and the way to fix it is by adding the method shouldComponentUpdate.

The shouldComponentUpdate by default always returns true allowing to render all the time, normally with small or medium components this should not represent a problem, but when we have a lot of logic into our components or we update constantly the state probably this can cause a performance issue.

shouldComponentUpdate receives two parameters: props and state, and needs to return a boolean value, if we return false we will block the render, otherwise, we will allow the component to render. That’s why you need to be careful when you use this method to not affect the component’s functionality. 

Many people get confused about when to use shouldComponentUpdate or when to use a Pure Component. Normally the Pure components are very useful when your components are pure, that means they always render the same result for the same inputs and they don't cause side effects. Also, Pure components do not include the shouldComponentUpdate method.

If you want to know more about how Pure components works, you can read the article Understanding how React Pure Components work.

Always prefer stateless component for static content

When you have to render static HTML always use stateless components (functional components), this normally is used for layout components or to display very simple information, the Stateless components do not have the life cycle methods like a Class components, is just the equivalent of the render method, that’s why using stateless components will improve significantly the performance of your React application.

Do not use indexes as keys for elements

Every time a component’s state changes, React fires the render method on the nodes again and compares the result with the previous tree of React elements. React is smart enough to figure out the minimum number of operations required to apply the expected changes on the view. This process is called reconciliation and it is managed transparently by React. 

Always React tries to apply the smallest possible number of operations on the DOM because changing the DOM is an expensive operation.

Let's see some example. When adding an element at the end of the children, converting between these two trees works well: 

<ul>
  <li>First</li>
  <li>Second</li>
</ul>

<ul>
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>

React will match the two <li>First</li> trees, match the two <li>Second</li> trees, and then insert the <li>Third</li> element.

But if you try to insert the element at the beginning this will have a poor performance: 

<ul>
  <li>First</li>
  <li>Second</li>
</ul>

<ul>
  <li>Third</li>
  <li>First</li>
  <li>Second</li>
</ul>

You can solve this problem by using keys, for example: 

<ul>
  <li key="1001">First</li>
  <li key="1002">Second</li>
</ul>

<ul>
  <li key="1000">Third</li>
  <li key="1001">First</li>
  <li key="1002">Second</li>
</ul>

With this React will know that the element with the key 1000 is the new one, and then the keys 1001 and 1002 have just moved.

Although numeric keys do the trick, is not recommended to use indexes as keys, this normally can have performance issues when you render a lot of elements with the same key, always prefer unique values for keys, those can be inclusively random strings.

Splitting your Webpack bundles

One of the best practices for Webpack is to split our bundles and break it down into two parts, one for our application and the other for our vendors (node_modules).

In Webpack 4 there is a new configuration called optimization: 

optimization: {
  splitChunks: {
    cacheGroups: {
      default: false,
      commons: {
        test: /node_modules/,
        name: 'vendor',
        chunks: 'all'
      }
    }
  }
}

Compressing your bundles with production mode

Webpack 4 does not need a configuration file by default. In version 3, you must use a configuration file. If you need to customize your Webpack 4 you can still create a configuration file, which will be way easier to configure.

Webpack now has 2 modes: development and production. By default, the production mode is enabled, that means will perform a minification and obfuscation to our bundles.

You can add the necessary scripts in your package.json to run Webpack with both modes: 

"scripts": {
  "build-development": "webpack --mode development",
  "build": "webpack --mode production" 
}
File: package.json

Analyzing our bundles with BundleAnalyzerPlugin

The BundleAnalyzerPlugin can help you to see all the vendor packages (node_modules) sizes; this will give you an image of the bundles organized by size (the big squares means big sizes and small squares means small size), you can install it with:

npm install --save-dev webpack-bundle-analyzer

Then in your plugins, you can add it like this:

import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

Then in the plugins node: 

{
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

Once the BundleAnalyzerPlugin is executed you will see a new page where displays all the installed packages, like this: 

BundlerAnalyzer-GLfRw.png

Then if you have split your bundles you will see also the components of your main bundle:

AppBundle-r744s.png

Enable GZip compression

You can enable GZip compression in your Nginx by editing the file nginx.conf with this: 

Only members can see all the codes
You can Login or Sign Up

You can get at least 15% or 20% more reduction in your bundles using GZip.

If you liked this post and you want to learn more about Webpack, React and optimization techniques then you should buy the React Cookbook.

avatarLeave a comment

Your comment

Only members can comment. You can Login or Sign Up