react 實現頁面代碼分割、按需加載

雖然一直有作 react 相關的優化,按需加載、dll 分離、服務端渲染,可是歷來沒有從路由代碼分割這一塊入手過,昨天在本地開發時沒有測試成功,今天又搞了下,已經部署到線上環境了,今天就這個記錄一下。javascript

修改配置

  • 開發環境:webpack@v3react-router@v4
  • 安裝依賴:css

    $ yarn add babel-plugin-syntax-dynamic-import -dev
  • 修改 .babelrc 文件:在 plugins 中添加 "syntax-dynamic-import"

改造項目代碼

  • 安裝依賴:java

    $ yarn add react-loadable
  • 根據 react-loadable 文檔提示,咱們須要提供一個載入新頁面時的 Loading 組件,同時對加載和超時狀態進行區別提示:react

    import React from 'react';
    import { Icon } from 'antd';
    
    const Loading = ({ pastDelay, timedOut, error }) => {
      if (pastDelay) {
        return <div><Icon type="loading" /></div>;
      } else if (timedOut) {
        return <div>Taking a long time...</div>;
      } else if (error) {
        return <div>Error!</div>;
      }
      return null;
    };
  • 更改頁面組件導入方法:webpack

    import React from 'react';
    import Loadable from 'react-loadable';
    import { Route, Switch } from 'react-router-dom';
    
    const Home = Loadable({
      loader: () => import('../Home'),
      loading: Loading,
      timeout: 10000
    });
    const EditArticle = Loadable({
      loader: () => import('../EditArticle'),
      loading: Loading,
      timeout: 10000
    });
    
    ...
    
    <Switch>
        <Route exact path="/home" component={Home} />
        <Route path="/editarticle" component={EditArticle} />
    </Switch>

    而後打包結果就會分離出各頁面代碼:git

    打包結果

    在頁面中咱們只須要載入入口文件 app.js ,其餘腳本在訪問到對應頁面時都會經由這個文件載入。github

驗證結果

在將靜態資源上傳到 cdn 以後,在頁面中加載 app.cssapp.js ,運行以後訪問各個頁面就會依次加載對應腳本,結果如圖:web

運行結果

能夠看到,在訪問第一個頁面時加載的頁面腳本經 gzip 壓縮後僅有 21.8KB !!!固然這與頁面複雜度也有關,可是相較於加載所有腳本,已是大幅減小了,這種優化對訪問目標性很強的用戶感覺起來尤其明顯。緩存

這麼作的另外一個好處就是當咱們只更改項目中某些頁面的業務代碼時,其餘頁面的代碼依然是不變的,因此這個時候其餘頁面用的是客戶端緩存,從另外一個層面又作了一次優化。bash

Tips

該文章首發於個人博客https://blog.bingqichen.me/

相關文章
相關標籤/搜索