React Code Splitting Routing-based Code Splitting Component Lazy Loading

Keywords: React Webpack ECMAScript Javascript

Pack

Most React applications will use Webpack Or Browserify Build tools like this to package files.Packaging is the process of introducing and merging files into a single file, resulting in a "bundle".The bundle is then introduced on the page, and the entire application can be loaded at once.

Example

App file:

// app.js
import { add } from './math.js';

console.log(add(16, 26)); // 42
// math.js
export function add(a, b) {
  return a + b;
}

Packed file:

function add(a, b) {
  return a + b;
}

console.log(add(16, 26)); // 42

Be careful:

Ultimately, your packaged file will look very different from the example above.

If you are using Create React AppNext.jsGatsby Or a similar tool, you will have a Web pack configuration that you can use directly for packaging.

If you are not using such a tool, you need to configure it yourself.For example, view the install and Introduction Tutorial.

Code Split

Packaging is a great technology, but as your applications grow, so will your code packages.Especially when you have integrated a large third-party library.You need to be aware of the code contained in your code package to avoid loading too long due to its size.

To avoid creating large code packages, it's a good choice to think about this earlier and split the code packages.Code splitting is done by methods such as Webpack( Code Split ) and Browserify ( factor-bundle ) A technology supported by such packers that creates multiple packages and loads them dynamically at runtime.

Code splitting for your app can help you "lazily load" what your current users need and significantly improve your app performance.Although it does not reduce the overall code volume of the application, you can avoid loading code that users will never need, and reduce the amount of code that needs to be loaded at the initial load.

import()

The best way to introduce code splitting in your application is through the dynamic import() syntax.

Before use:

import { add } from './math';

console.log(add(16, 26));

After use:

import("./math").then(math => {
  console.log(math.add(16, 26));
});

Be careful:

Dynamic import() grammar is currently just an ECMAScript (JavaScript) proposal Rather than formal grammar standards.Formal acceptance is expected in the near future.

When a Webpack parses into this grammar, it automatically starts splitting code.If you use Create React App, the feature is configured and you can Use it now This feature. Next.js This feature is also supported without further configuration.

If you configure the Webpack yourself, you may want to read about Webpack Code Split Guidelines.Your Webpack configuration should Like this.

When used Babel When you do, you want to make sure that Babel can parse the dynamic import syntax instead of converting it.For this requirement you need babel-plugin-syntax-dynamic-import Plug-in.

React.lazy

Be careful:

React.lazy and Supense technologies do not yet support server-side rendering.If you want to use in applications that use server-side rendering, we recommend Loadable Components This library.It has a great Service-side Rendering Packaging Guide.

The React.lazy function allows you to handle dynamically imported components like rendering regular components.

Before use:

import OtherComponent from './OtherComponent';

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

After use:

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

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

This code will automatically import the package containing the OtherComponent component when rendering the component.

React.lazy accepts a function that requires a dynamic call to import().It must return a Promise that requires a Remove component of resolve, defalut export.

Suspense

If the module containing OtherComponent has not been loaded yet after rendering of MyComponent, we can use the load indicator to elegantly downgrade the component.Here we use the Suspense component to solve this problem.

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

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

The fallback property accepts any React elements that you want to show during component loading.You can place the Suspense component anywhere on top of the lazily loaded component.You can even wrap multiple lazy loading components in one Suspense component.

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

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

Exception Capture Boundaries

If the module fails to load (such as a network problem), it triggers an error.You can pass Exception Capture Boundaries Technology handles these situations to show a good user experience and manage recovery.

import MyErrorBoundary from './MyErrorBoundary';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

const MyComponent = () => (
  <div>
    <MyErrorBoundary>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </MyErrorBoundary>
  </div>
);

Route-based code splitting

Deciding where to introduce code splitting requires some skill.You need to make sure that the chosen location can evenly divide the code package without affecting the user experience.

A good choice is to start with routing.Most web users are accustomed to having a load-switching process between pages.You can also choose to re-render the entire page so that your users do not have to interact with other elements on the page while rendering.

Here is an example of how you can use React.lazy and React Router A third-party library such as this one to configure Routing-based code splitting.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);

Named Exports

React.lazy currently only supports default exports.If you want the imported module to use named exports, you can create an intermediate module to re-export to the default module.This guarantees that tree shaking will not fail and that unnecessary components will not be introduced.

// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));

Posted by primuz on Sun, 28 Jul 2019 19:16:42 -0700