webpack實戰——代碼分片

前言

這是webpack實戰系列筆記的第9篇記錄——代碼分片,前幾篇記錄如下:

  • 打包第一個應用
  • 模塊化與模塊打包
  • 資源輸入與輸出
  • 一切皆模塊
  • 預處理器【上篇】
  • 預處理器——常用loader【下篇】
  • 樣式文件分離
  • 樣式預處理

代碼分片

實現高性能應用其中重要的一點就是儘可能的讓用戶每次只加載必要的資源,優先級不太高的資源則採用延遲加載(懶加載)等技術漸進式的獲取,這樣可以保證首屏頁面加載的速度。
代碼分片是Webpack作爲打包工具所特有的一項技術,通過這項技術我們可以把代碼按照特定的形式進行拆分,使用戶按需加載。

通過入口劃分代碼

通過入口配置進行一些簡單有效的代碼拆分。

對於web應用來說通常會有一些庫和工具是不常變動的,可以將它們放在一個單獨的入口中,由該入口產生的資源不會經常更新,因此可以有效地利用客戶端緩存,讓用戶不必在每次請求頁面時都讓資源重新加載。

// webpack.config.js

...
entry:{
    app: './src/app.js',
    lib: ['lib-a', 'lib-b', 'lib-c']
}
<!--index.html-->
...

<script src="./dist/lib.js"></script>
<script src="./dist/app.js"></script>

這種拆分方法主要適用於那些將接口綁定在全局對象上的庫,因爲業務代碼中的模塊無法直接引用庫中的模塊,而這屬於不同的依賴樹。

但這樣仍會帶來新的問題:公共模塊與業務模塊處於不同依賴樹的問題以及很多頁面並不需要公共模塊的問題。

optimization

在webpack4之前,做代碼切片使用的是CommonsChunkPlugin,而在4及之後,取而代之的是optimization

optimization.SplitChunks簡稱optimization,是Webpack4爲了改進CommonChunkPlugin而重新設計和實現的代碼分片特性。

舉例

1. 安裝

// 兩種方式二選一
yarn add optimization react
// 或
npm install optimization react

2. a.js & b.js

// a.js
import React from 'react'
import('./b.js');
document.write('a.js', React.version)
// b.js
import React from 'react'
console.log('b.js', React.version)

3. webpack配置

// webpack.config.js
module.exports = {
    entry: './src/a.js',
    output: {
        filename: 'a.js',
        publicPath: '/dist/'
    },
    mode: 'development',
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    }
}

4. 打包

yarn build
// 或
npm run build

結果如圖所示:

特性

首先觀察上面的配置,從上面的配置項中可以看到:

  • 指定了chunks的值是all,含義是:SplitChunks將會對所有的chunks生效;
  • mode:之前也一直在用,其實是Webpack4中新增的配置項,可以針對當前是開發環境還是生產環境自動添加一些對應的Webpack配置。

而從上圖打包結果中看,可以看到三個文件包:0.a.jsa.jsvendors~main.a.js。其中,vendors~main.a.js則是將react提取到了裏面。

提取條件

  • 提取後的chunk可悲共享或者來自node_modules目錄。
  • 提取後的JS chunk體積大於30kB(壓縮和gzip前),CSS chunk體積大於50kB。
  • 按需加載過程中,並行請求的資源最大值小於等於5。
  • 首次加載時,並行請求的資源數最大值小於等於3。

需要注意的是,默認提取方式爲異步提取。

配置

分爲四類:

  • 匹配模式
    通過chunks可以配置Splitchunks的工作模式:async(默認),initial和all。async即只提取異步chunk,initial只對入口chunk生效,all則兩種模式同時開啓。
  • 匹配條件
    minSize、minChunks、maxAsyncRequests、maxInitialRequests都屬於匹配條件。
  • 命名
    配置項name默認爲true,意味着SplitChunks可以根據CacheGroups和作用範圍自動爲新生成的chunk命名,並且以automaticNameDelimiter分割。
  • CacheGroups
    可以理解爲分離chunks時的規則。

默認配置

module.exports = {
    ...

    splitChunks: {
        chunks: 'async',
        miSize: {
            javascript: 30000,
            style: 50000,
        },
        maxSize: 0,
        minChunks: 1,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        automaticNameDelimiter: '~',
        name: true,
        cacheGroups: {
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10
            },
            default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true
            }
        }

    }
}

小結

本篇瞭解了兩種代碼分片方式:

  • 入口規劃
  • SplitChunks

而藉助這些方法,我們可以有效的縮小資源體積,更好的利用緩存,從而給用戶更有好的體驗度。

下一篇介紹生產環境優化中的一些配置,如環境配置封裝、sourceMap等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章