H5 分包實現首屏加載時間優化

H5 分包實現首屏加載時間優化

1、爲何首屏加載須要優化

由於作了不少事情:css

初始化 webView -> 請求頁面 -> 下載數據 -> 解析HTML -> 請求 js/css 資源 -> dom 渲染 -> 解析 JS 執行 -> JS 請求數據 -> 解析渲染 -> 下載渲染圖片node

dom渲染 以前用戶看到的都是白屏,在 下載渲染圖片 後,用戶才能看到完整的頁面。首屏秒開優化就是要減小這個過程的耗時。react

扣除網絡差的緣由,對首屏啓動速度影響最大的就是網絡請求。因爲業務需求,致使咱們不得不引入不少第三方包來實現功能,這些包偏偏會容易影響到網絡請求。webpack

這裏咱們把大致積的包,分紅多個小體積的包進行加載,減小請求時間web

2、分析產物

經過分析產物來查看打出來的包內容佔比bash

yarn build
複製代碼

打完包後若是出現下面黃色文字,說明打出來的包體積過大,咱們用百度翻譯來看下解釋: 網絡

在這裏插入圖片描述

束的大小明顯大於推薦值。
考慮使用代碼拆分來減小它:https://goo.gl/9VhYWB
您還能夠分析項目依賴關係:https://goo.gl/LeUzfb
複製代碼

你的包大小超過了推薦值,能夠經過分析項目依賴進行的分包處理。antd

umialita 項目中,執行 ANALYZE=1 umi buildANALYZE=1 alita build 來分析下產物。echarts

在這裏插入圖片描述

咱們能夠看到通過壓縮後的 umi.js 還有 1.2M 的大小。dom

在這裏插入圖片描述

umi.js 下最大的包是筆者引入的 echarts,有 211kb 的大小,這裏只是引入了一個 echart 包,若是項目中,多引入一些大致積包的話,那麼 umi.js 的大小就不是 1M 而會更大,在首屏加載時,請求這些數據就嚴重影響到了下載和渲染時間。

這時,對包的拆解就顯得尤其重要了。

3、分包實現

打開 config/config.ts 文件(若是是 umi2 的項目則是 .umirc.js)

export default {
  chainWebpack(config) {
    config.optimization.splitChunks({
      chunks: 'all',
      automaticNameDelimiter: '~',
      name: true,
      minSize: 30000,
      minChunks: 1,
      cacheGroups: {
        echarts: {
          name: 'echarts',
          test: /[\\/]node_modules[\\/](echarts)[\\/]/,
          priority: -9,
          enforce: true,
        },
        vendors: {
          name: 'vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -11,
          enforce: true,
        },
      }
    })
  },
  chunks: ['vendors', 'echarts', 'umi'],
}
複製代碼

咱們先看下 cacheGroups 下的屬性,其餘屬性在下文中會講解,先實現需求爲重。

cacheGroups 下的屬性爲 key-value 的對象形式,key 能夠自行命名,那 value 的值呢,咱們繼續往下看:

  • name: 拆分塊的名稱,提供字符串或函數使您可使用自定義名稱,若是 namechunks 名稱匹配,則進行拆分。
  • test: 正則匹配路徑,符合入口的都會被拆分,裝到 name 名稱下的包中。
  • priority: 拆包的優先級,越大優先級越高。順序很重要,先把大包分出去,在將剩餘的 node_modules 分紅 vendors 包。
  • enforce: 無論這個包的大小,都會進行分包處理。

如今咱們再執行 ANALYZE=1 umi build 看看效果:

在這裏插入圖片描述

echarts 包已經從 umi.js 中拆分出來,umi.js 的大小縮小到 800K 左右,這時經過 yarn build 打包不會才提示包過大的內容了。可是爲了進一步演示,咱們能夠把上圖中較大的包如 antd-mob ile 或者 antd 組件庫的包也分出來。

在上面的代碼 cacheGroups 中補充:

antdm: {
  name: 'antdm',
  chunks: 'all',
  test: /[\\/]node_modules[\\/](@ant-design|antd|antd-mobile)[\\/]/, // 這裏模擬有 antd 的狀況,請根據實際項目具體考慮分析
  priority: -10,
  enforce: true,
},
複製代碼
chunks: ['vendors', 'echarts', 'umi', 'antdm'],
複製代碼

在這裏插入圖片描述

由圖得知,組件庫的包被分出來了 umi.js 由變小了一點點。

這裏補充一點呢,不建議拆分過小包,好比上述的 antdm 由於意義不大。

4、解析 splitChunks

第三大點,咱們着重分析了 cacheGroups, 如今咱們來分析下其他的字段,官網文檔有解析,不過感受對於有些像我這樣的初學者來講閱讀起來會比較生澀一點,因此也能夠下文中我對某些字段的解釋,應該會來的通俗易懂一點點。

chunks: 有效值爲:all|async|initial

參數 含義
all 把動態和非動態模塊同時進行優化打包;全部模塊都扔到 vendors.bundle.js 裏面。
async 把動態模塊打包進 vendor,非動態模塊保持原樣(不優化)
initial 把非動態模塊打包進 vendor,動態模塊優化打包
  • 動態引入模塊: import ('lodash')
  • 非動態引入模塊: import 'react'

筆者推薦一篇文章詳細講解了 chunks 參數的含義:webapck4 玄妙的 SplitChunks Plugin

maxAsyncRequests: async 時並行請求的最大數量。在作一次按需加載的時候最多有多少個異步請求,爲 1 的時候就不會抽取公共 chunk 了

maxInitialRequests: initial 時並行請求的最大數量。同上。

minChunks: 拆分前必須共享模塊的最小塊數。指某個模塊最少被多少個入口文件依賴。當大於等於minChunks設定的值時,該模塊就會被打包到公用包中。小於這個值時,該模塊就會被和每一個入口文件打包在一塊兒。

minSize: 被拆分出的bundle在拆分以前的體積的最小數值,只有 >= minSize 的bundle會被拆分出來。

maxSize: 被拆分出的bundle在拆分以前的體積的最大數值,默認值爲0,表示bundle在拆分前的體積沒有上限。maxSize若是爲非0值時,切忌小於minSize。

star 點一點呀~

相關文章
相關標籤/搜索