Skip to content
Sandny Blog
  • Home
  • Java
  • JavaScript
  • AWS
  • Embedded
  • About
optimize React.js load time JavaScript

How to optimize React.js app load time using react…

  • August 1, 2021August 1, 2021
  • by Coder Kai

Often React.js applications could grow larger and could be taking more time to load the content. React team offered a very useful technique to lazily load the bundled content without bundling it all together with the main bundle. This will optimize the load time and show the content without taking much time to load the content fully.

What is React.lazy?

Before all of these lazy loading and more involvement with package bundlers, the way to optimize load time was to import the code splitted into two or more by using dependencies or injections. So initial content is loaded with a light weight code bundle and other heavy parts are eventually loaded after the web page is rendered.

When ECMA proposed the method of dynamic imports, it was a very useful method to adhere code splitting without worrying about what to split and dependencies throughout since we can check its functionality even in dev mode. https://github.com/tc39/proposal-dynamic-import this link has a proposal of its usage with dynamic import syntax.

Package bundlers like Webpack most willingly supported this and this lead to many code splitting and dynamic loading concepts for frameworks like React, Angular and Vue.js

So what is React.lazy? Simply its a way of loading content dynamically to render without blocking the rendering until all the content is loaded. You can declare it as follows.

// load content dynamically
const ProfileComponent = React.lazy(() => import('./ProfileComponent'));

So to use this there are few important steps in React.js. Mainly we will answer;

  1. How code is splitted when you use React.js
  2. Showing a loading component when the dynamic content is downloading.
  3. Measing optimization using lighthouse

How to split your code using React.lazy and optimize React.js load time

For this we will use a simple example to demonstrate how to use dynamic loading.

optimize React.js load time with react.lazy

This will load the examples from chart.js which is a common example to load stock data or reports. Lets look at the code on how to load them

import React, {Suspense} from 'react';
import Loader from "react-loader-spinner"; 
import Line from './components/Line';
import './App.css';

const App = () => {
  return (
    <div className="App">
      <div className="Col">
        <StockChart />
      </div>
      <div className="Col">
        <Line />
      </div>
    </div>
  );
}

export default App;

When we build this example we can see the following js bundles in the build folder.

Splitted code when loading the component

Now we will change the StockChart into dynamic loading, here we need to use the React.Suspense component to wrap the component until the data is loaded.

import React, {Suspense} from 'react';
import Loader from "react-loader-spinner"; 
import Line from './components/Line';
import './App.css';

const StockChart = React.lazy(() => import('./components/StockChart'));

const App = () => {
  return (
    <div className="App">
      <div className="Col">
        <Suspense fallback={<Loader type="Bars" color="#00BFFF" height={80} width={80} />}>
          <StockChart />
        </Suspense>
      </div>
      <div className="Col">
        <Line />
      </div>
    </div>
  );
}

export default App;

Now you can see an extra bundle when you run yarn build to produce the bundled code using webpack. This is the dynamic loading component that will be loaded over the network once the content is loaded

Splitted code when loading the component

To demonstrate how the loading is visualized I will add a loading animation to the chart component and visualize it with a timeout which is equivalent to loading a chunk parallelly through a network.

import React, {Suspense} from 'react';
import Loader from "react-loader-spinner"; 
import Line from './components/Line';
import './App.css';

const StockChart = React.lazy(() => {
  return new Promise((res) => {
    setTimeout(() => {
      res(import('./components/StockChart'));
    }, 5000);
  })
});

const App = () => {
  return (
    <div className="App">
      <div className="Col">
        <Suspense fallback={<Loader type="Bars" color="#00BFFF" height={80} width={80} />}>
          <StockChart />
        </Suspense>
      </div>
      <div className="Col">
        <Line />
      </div>
    </div>
  );
}

export default App;
optimize React.js load time

Now you can see that the loader is shown when the component is loading. Any component that you add in suspense will load until the component is loaded over the network.

        <Suspense fallback={<Loader type="Bars" color="#00BFFF" height={80} width={80} />}>
          <StockChart />
        </Suspense>

How to handle the error when loading the component

Sometimes there could be errors when loading suspense components due to network conditions or many different reasons. The following code demonstrates how to handle it within the parent component just as Suspense component.

import React, {Suspense} from 'react';
import Loader from "react-loader-spinner"; 
import Line from './components/Line';
import './App.css';

const StockChart = React.lazy(() => {
  return new Promise((res, rej) => {
    setTimeout(() => {
      rej();
    }, 2000);
  })
});

const App = () => {
  return (
    <div className="App">
      <div className="Col">
        <ErrorBoundary fallback={<div>Error loading component</div>}>
          <Suspense fallback={<Loader type="Bars" color="#00BFFF" height={80} width={80} />}>
            <StockChart />
          </Suspense>
        </ErrorBoundary>
      </div>
      <div className="Col">
        <Line />
      </div>
    </div>
  );
}

class ErrorBoundary extends React.Component {
  state = { hasError: false, error: null };
  static getDerivedStateFromError(error) {
    return {
      hasError: true,
      error
    };
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}

export default App;
optimize React.js load time

Note that there is no hook to catch these errors within the component. So we will have to use the class as shown in the code.

How to measure the load time opitimization

You can use Lighthouse plugin with chrome to create a report of load time and other measurements to see how your website is performing.

First without the suspense.

Next when we add the suspense for both the Line and StockChart components.

You can see that the contentful paint took has a 0.1s optimization with lighthouse score criteria. This could be optimizing much more when you have a large content to load.

I think you got an overall good understanding of how to optimize React.js load time using dynamic loading in react. Feel free to leave a comment if you need more information.

How to convert a string into a stream of lines using String.lines() method in Java 11
Python is not setting correct path in mac os
Coder Kai
A humble developer
dynamic loading optimize react.js react.lazy suspense suspense error handling

Related articles

Multiple refs for an array of React Elements
Using multiple refs for an…
Immutable and Mutable Values in Javascript
07. Immutable and Mutable Values…
wrapper objects in javascript
06. Wrapper objects in Javascript
globals undefined and null values in javascript
05 Global, null and undefined…
Javascript Booleans and Equality
04. Javascript Guide Booleans and…
How to add Chakra UI Animations
Chakra UI Animations
SSL Websocket using Nginx Proxy
SSL Websocket proxy with Nginx…
Change python version correctly
Python is not setting correct…
Multiple refs for an array of React Elements
How to use IntersectionObserver to…
Multiple refs for an array of React Elements
How to dismiss dropdowns when…
Javascript guide Strings
03. Javascript Guide – Strings
How to fetch data with useEffect
How to fetch data with…
add styles to stripe elements
How to add styles to…
Typescript
How to use Typescript with…
how to optimize react-native map view
How to optimize react-native map…
debounce with react hooks
Avoid multiple clicks using debounce…
Numbers inJavascript
02. Javascript Guide – Numbers
Introduction to Javascript
01. Javascript Guide – Introduction…
Nginx Load Balancer with docker…
Create React App Using npx

Categories

  • android 3
  • Apollo Client 1
  • AWS 8
    • AppSync 5
    • EC2 1
    • EKS 1
    • Route53 1
    • S3 1
  • AWS Amplify 1
  • Chakra UI 1
  • Docker 1
  • Embedded 1
  • EmberJS 1
  • FCM 1
  • Godaddy 1
  • GraphQL 3
  • ios 1
  • Jasper 1
  • Java 10
    • Java 11 1
    • Java 14 1
  • JavaEE 2
  • JavaScript 39
    • Express.js 4
    • Javascript Guide 7
    • Node.js 3
    • react-native 4
    • React.js 17
    • Typescript 1
  • Kubernetes 1
  • machine learning 1
  • Maven 2
  • OCaml 3
  • PostgreSQL 1
  • Python 2
  • react-native 4
  • ReactJS 3
  • sass 1
  • Server 6
  • spark 1
  • Terraform 2
  • Ubuntu 4
  • Uncategorized 1
  • webpack 2

Recent Comments

  • binance Registrera dig on Higher order component wrappers using React.js and reusable components.
  • kopya site buyhacklink.com on How to create Lambda function with Terraform
  • Pamela587 on Chakra UI Animations

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Archives

  • October 2022 3
  • September 2022 7
  • May 2022 1
  • December 2021 1
  • August 2021 1
  • July 2021 6
  • June 2021 3
  • February 2021 1
  • July 2020 1
  • December 2019 5
  • November 2019 6
  • October 2019 3
  • August 2019 1
  • March 2019 1
  • February 2019 1
  • January 2019 2
  • December 2018 1
  • September 2018 2
  • August 2018 1
  • June 2018 1
  • February 2018 1
  • November 2017 2
  • October 2017 5
  • September 2017 1
  • June 2017 1
  • May 2017 10
Sandny Blog space
Theme by Colorlib Powered by WordPress