1. 程式人生 > 程式設計 >React中程式碼分割的4種實現方式

React中程式碼分割的4種實現方式

目錄
  • 前言
  • import()
  • React.lazy
  • import() + React Loadable
  • Umi 按需載入
  • 總結

前言

在 React 應用中,我們通常的做法是直接將某個模組匯入到頁面中,這樣做導致的結果是打包出來的包體積過大。尤其是在引入了體積巨大的第三個庫的情況下,打包後的包體積會十分巨大。因此,我們需要關注我們的應用中所包含的程式碼,以避免因體積過大而導致載入時間過長。

對程式碼進行分割能夠“懶載入”當前使用者所需要的內容,能夠顯著提高應用的效能。儘管並沒有減少應用的整體程式碼體積,但可以避免載入使用者永遠不需要的程式碼,並在初始載入的時候可以減少所需載入的程式碼量。

下面,我們分別來介紹下在 React 中實現程式碼分割的幾種方式。

import()

import() 是 Webpack 提供的用於分割程式碼的一個方法。該方法的返回結果是Promise,當檔案載入完成後悔將模組匯出給 promise.then 方法的回撥。

例如有一個 math 模組,匯出了 add方法和 minus 方法:

export const add = (a,b) => {
	return a + b;
}

export const minus = (a,b) => {
	return a - b;
}

通常的做法是在頁面直接引入模組:

import { add } from './math'

console.log(add(5,10));

使用 import 動態匯入模組:

import('./math').then((math) => {
	console.log(math.add(5,10))
})

當 Webpack 解析到該語法時,會自動進行程式碼分割。如果是使用 Create React App 建立的 React 應用,import 功能已開箱即用。

import React,{ Component } from 'react';

class App extends Component {
  handleClick = () => {
    import('./math')
      .then(({ add }) => {
        add(5,10)
      })
      .catch(err => {
        // Handle failure
      });
  };

  render() {
    return (
      <div>
        <button onwww.cppcns.com
Click={this.handleClick}>兩數相加</button> </div> ); } } export default App;

React.lazy

React.lazy 方法可以讓我們動態載入元件,有助於縮減打包後 bundle 的體積,並延遲載入在初次渲染時未用到的元件。

React.lazy 接受一個函式,這個函式需要動態呼叫 import()。它必須返回一個 Promise,該 Promise 需要 resolvwww.cppcns.come 一個 export default 的 React 元件。

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

React.lazy 返回的是一個非同步元件 不能單獨使用,需要配合 React.Suspense 使用。當這個非同步元件的狀態是 pending 時顯示的是 Suspense 中 fallback 的內容,只有 resolve 時才會顯示載入好的元件。如此使得我們可以在使用 lazy 元件時做優雅降級(如在 fallback新增 loading 效果等)。

import React,{ Suspense } from 'react';

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

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

import() + React Loadable

React Loadable 是一個輕量級的程式碼分割元件,它是一個高階元件,能讓你的應用程式在渲染之前動態的載入任何模組。

使用 import() + React Loadable ,能優雅的實現基於 react-router 4.x 版本的路由分割:

import Loadable from 'react-loadable';

const LoadableBar = Loadable({
  loader: () => import('./components/Bar'),loading() {
    return <div>zLHdToKNtnLoading...</div>
  }
});

class MyComponent extends React.Component {
  render() {
    return <LoadableBar/>;
  }
}

在實際業務開發中,我們通常會使用一些框架來快速開發React應用。在這些框架中,通常都會提供按需載入的功能。下面,我們來看看 UmiJS 框架中的按需載入。

UmiJS 按需載入

UmiJS 是一個可擴充套件的企業級前端應用框架,它以路由為基礎,支援配置式路由和約定式路由。UmiJS 封裝了一個 dynamic 元件來實現程式碼分割。

啟用按需載入

UmiJS 的按需載入功能預設是關閉的,需要在使用之前通過配置開啟。在 UmiJS 專案中新增如下的配置開啟:

export dehttp://www.cppcns.comfault {
  dynamicImport: {},}

使用按需載入

首先封裝一個非同步元件:

import { dynamic } from 'umi';
export default dynamic({
  loader: async function() {
    // 這裡的註釋 webpackChunhttp://www.cppcns.comkName 可以指導 webpack 將該元件 HugeA 以這個名字單獨拆出去
    const { default: HugeA } = await import(/* webpackChunkName: "external_A" */ './HugeA');
    return HugeA;
  },});

然後使用封裝好的非同步元件:

import React from 'react';
import AsyncHugeA from './AsyncHugeA';

export default () => {
  return <AsyncHugeA />;
}

總結

到此這篇關於React中程式碼分割的文章就介紹到這了,更多相關React程式碼分割內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!