【Day15】代码分割 & 延迟载入 Code Splitting & Lazy loading

打包 Bundle

bundle 的英文原意是指将东西捆成一綑,
而在程序用语中
所谓的 bundle 即是将被 import 的档案
合并成一个单一的档案,
再将这个 bundle 档案引入到
网页内来载入完整的应用程序。

React 常见的 bundle 套件有:

  • Webpack(Create React App、Next.js、Gatsby 内建)
  • Rollup
  • Browserify

代码分割 Code Splitting

随着应用程序成长,
bundle 也会随之长大,
为了避免 bundle 的出来的档案过大,
最好的解决问题的方式是开始
「split」这个 bundle 档案。

Splitting 是 Webpack 等 bundler 支援的功能,
会建立多个 bundle,runtime 时再动态载入。

Code-Splitting 目前已成为部分套件软件预设功能,
使用 Create React App、Next.js 等套件打包时,
皆会自动对代码执行 Code-Splitting。


延迟载入 Lazy loading

Code-splitting 可以「延迟载入」
目前使用者还不需要的东西,
避免载入使用不到的程序码,
来减少初始载入应用程序的时间。

以下纪录几种延迟载入的方法:

  • 动态 import(ES6)
  • React.lazy
  • loadable-components

动态 import(ES6)

加入前:

import { add } from './math';

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

加入後:

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

React.lazy

  • 不借助任何附加库就能通过代码分割(code splitting)延迟加载 React 组件
  • 页面级别的按需加载(只加载目前页面需要使用的代码)
  • 使用 React.Suspense 时,Suspense 里面必须要有 fallback,其内容是尚未加载完毕时页面显示的内容
import React, { Suspense } from 'react';

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

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

React.lazy 和 React.Suspense 尚不支持server render,如果要使用server render,可使用 loadable-components


loadable-components

import loadable from '@loadable/component'

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

function MyComponent(){ ... }

错误边界

当 module 载入失败时会触发错误,
可以透过错误边界处理这些错误
来呈现好的使用者体验和管理恢复。

建立错误边界後,
就可以在 lazy component 上层套用它,
让网路发生错误时能主动显示错误状态。

import React, { Suspense } from 'react';
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>
);

Named Exports

React.lazy 目前只支援 default exports。
如果想 import 的 module 使用 named export,
可以建立一个中介 module 来重新 export 它,
以确保 tree shaking 不会 pull 无用的 component。

【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"));

参考资料


<<:  [Day 17] v-model双向绑定是什麽咧??

>>:  Day 18 : 静态爬虫

JavaScript学习日记 : Day3 - 基本型别(一)

1. 型别总览 JavaScript中的数据都是有型别的,共有八种型别: 数字(Number) 字串...

day11_MacOs ARM 的音乐之旅

音乐播放器 虽然 Mac Os , Linux, Windows 都内建了音乐播放器,但他们仍有一些...

Day 29 Google Play评论爬取

今天的影片内容为爬取Google Play网页版应用程序的评论 并将前几天爬取AJAX网页(Dcar...

Day20 浅谈AJAX?

大家好我是乌木白,今天要和大家介绍的是 AJAX,AJAX 是我在学习 JavaScript 这门...

Day23 :【TypeScript 学起来】先了解 ES6 Class

因为我没什麽用到 Class,这一篇会笔记 ES6 Class 的使用, 下一篇才会进到 Type...