Use React.lazy () to load components on demand to improve application performance!

May 19, 2023 1484hotness 0likes 0comments

as the scale of the React application we develop is getting larger and larger, if all the components are still packaged into one bundle file, it may cause the application to load slowly. It is a common practice to package the components in the program into separate files to reduce the load time of the application, which is usually achieved by "loading on demand". In this article, you will learn about the dynamic import of components in React programs.

1.roomnbsp; what is a dynamic import component?

dynamic import components refer to loading components when needed, rather than packaging all components into a single bundle file when the application loads. How do we implement it in React?

React provides us with a & nbsp; lazy () & nbsp; method and & nbsp; Suspense & nbsp; component, which are the two main tools for dynamically importing components.

using & nbsp; React.lazy () , we can easily load components on demand. The syntax is as follows:

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

in the code above, React.lazy () & nbsp; receives a function that returns a & nbsp; import () & nbsp; function call. import () & the nbsp; function is part of the ECMAScript dynamic import syntax, which allows us to load a module asynchronously at run time. By combining the & nbsp; React.lazy () & nbsp; with the & nbsp; import () & nbsp; function, we can load components on demand.

when we use & nbsp; React.lazy () & nbsp;, React automatically wraps the returned component in a & nbsp; lazy & nbsp; component. Therefore, we need to use the & nbsp; Suspense & nbsp; component to render the & nbsp; lazy & nbsp; component. Suspense & the nbsp; component allows us to display a loading interface before the component has finished loading. Here is a simple example of using the & nbsp; React.lazy () & nbsp; and & nbsp; Suspense & nbsp; components:

import React, { lazy, Suspense } from 'react';

const MyComponent = lazy(() => import('./MyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <MyComponent />
      </Suspense>
    </div>
  );
}

in the above code, when the & nbsp; & lt;MyComponent / & gt; & nbsp; component is rendered, React automatically loads the & nbsp; MyComponent & nbsp; module asynchronously. The fallback & nbsp; property specifies the loading interface that is displayed when the component loads. When the component finishes loading, React will render it automatically.

2. Example of asynchronous list components

Let's demonstrate React.lazy () and Suspense through an example of the Asynchronous list component. Let's first look at the final effect:

demonstration effect

2.1Parental component ArtistPage

We implement the effect in gif above through a parent component ArtistPage and a child component Albums. The idea of implementing the parent component ArtistPage is as follows:

After the

  1. page is loaded, the Open The Beatles artist page button is rendered by default. If the button is clicked, the list data is displayed.
  2. before showing the list data, first display a transitional Loading page through Suspense, and then display the list data after the sub-component and its data request is completed.

parent component ArtistPage code is as follows:

import { Suspense, useState } from "react";

import Albums from "@/components/Albums";

export default function ArtistPage() {
  const [show, setShow] = useState(false);

  // define the status show of the component, and control the rendering of the component
  // set it to false initially, and set it to true after clicking the button
  // to display the album page of The Beatles
  if (show) {
    // if show is true, render the following
    return (
      <>
        <h1>The Beatles</h1>
{/ * use React Suspense to wrap components and add fallback UI * /}
<Suspense fallback={<Loading />}>
{/ * pass in artistId attribute to render The Beatles album * /}
<Albums artistId="the-beatles" />
        </Suspense>
      </>
    );
  } else {
    // if show is false, render the following button
    return (
      <button onClick={() => setShow(true)}>
        Open The Beatles artist page
      </button>
    );
  }
}

// define Loading components for display when data is loaded
function Loading() {
  return <h2>🌀 Loading...</h2>;
}

when the user clicks the "Open The Beatles artist page" button, the status of the component is updated and a list of The Beatles is rendered on the page. On this page, the list data of The Beatles is displayed through React Suspense and component Albums. The Suspense component can handle the wait state when data is loaded asynchronously and show the components specified by the fallback property. In the parent component ArtistPage above, fallback shows a Loading component that shows the wait state during data loading.

2.2 subcomponent Albums

We will render the child component data list based on the parameter articleId field passed in by the parent component ArtistPage above. The sample code is as follows:

import { fetchData } from "./data";

// Note: this component uses an experimental API and is not available in a stable version of React.
// if you want a real example, try using a framework integrated with Suspense, such as Relay or Next.js.

// Albums component, which receives an artistId parameter of type string
export default function Albums({ artistId }) {
  // obtain the album data under artistId through the fetchData function, and wrap it with the use function
  const albums = use(fetchData(`/${artistId}/albums`));
  return (
    // render album list
    <ul>
      {albums.map((album) => (
        <li key={album.id}>
          {album.title} ({album.year})
        </li>
      ))}
    </ul>
  );
}

// this is a temporary function to make the demo program work properly.
// TODO: replace this function with a real implementation.
function use(promise) {
  // if the promise status has been completed, the result is returned.
  if (promise.status === "fulfilled") {
    return promise.value;
  } 
  // if the promise status is rejected, an exception is thrown
  else if (promise.status === "rejected") {
    throw promise.reason;
  } 
  // if the promise status is pending, an exception is thrown
  else if (promise.status === "pending") {
    throw promise;
  } 
  // if the promise status is unknown, set the status to suspend first, and then wait for the promise result
  else {
    promise.status = "pending";
    promise.then(
      (result) => {
        promise.status = "fulfilled";
        promise.value = result;
      },
      (reason) => {
        promise.status = "rejected";
        promise.reason = reason;
      }
    );
    throw promise;
  }
}

the use function in the above code is used to simulate the request for asynchronous data, simulating the process of getting data. If you have the foundation of Express or Koa, you can build a simple back-end service locally and replace the logic of the use function with a real asynchronous request. The use method here fetches the data and renders the returned data into an unordered list. During this process, Suspense exposes the components in the fallback property of the parent component when the data is not loaded. The component in fallback is the Loading component.

the end result is what gif looks like.

demonstration effect

3. Summary

dynamically importing components is an effective way to optimize the performance of React applications, allowing us to load components on demand as needed, rather than packaging all components into a single file when the application loads. Using the & nbsp; React.lazy () & nbsp; and & nbsp; Suspense & nbsp; components, we can easily import components dynamically. However, although dynamic import components can improve the performance of our program, there are still some things to pay attention to:

  • React.lazy () & nbsp; applies only to the default export component. If you want to load named exported components on demand, you need to use the normal dynamic import syntax.

  • because the dynamic import component requires a network request, it may have an impact on performance. Therefore, it is best to use dynamic import components with code segmentation techniques to load only the code you need.

  • when using & nbsp; React.lazy () & nbsp;, we must use the & nbsp; Suspense & nbsp; component. Rendering problems may occur if the & nbsp; Suspense & nbsp; component is not used.

  • in some cases, React.lazy () & nbsp; may not work properly. For example, if the component you want to import dynamically is in the & nbsp; node_modules & nbsp; directory, it may not work properly. At this point, we need to use other methods of loading components on demand, such as using a third-party library & nbsp; loadable-components .

  • if Webpack 4 or later is used in the project, we can use & nbsp; webpackChunkName & nbsp; with & nbsp; React.lazy () to provide a more meaningful name for dynamically loaded blocks of code. For example:

       const   MyComponent  =  lazy  (
     () = & gt;   import  ( / * webpackChunkName: "my-component" * /   ". / MyComponent" )
    );
     copy code   

    in the code above, we provide a name for the imported code block named & nbsp; "my-component" & nbsp;. This name is the name of the generated code block so that we can identify and debug it more easily.

I believe that through the above example you should understand React.lazy () and Suspense, proficiency in them is a must for advanced and advanced React development.

InterServer Web Hosting and VPS

Aaron

Hello, my name is Aaron and I am a freelance front-end developer

Comments