專案效能優化之給dist資料夾中chunk-vendors.js做splitChunks分包,從而減少首屏載入時間

水冗水孚 發表於 2022-06-27

問題描述

我們專案做完,驗收通過以後,就需要打包釋出上線啦。於是我們執行命令:npm run build打dist包,打包完以後截圖如下:

直接打包的chunk-vendors.js太大了

專案效能優化之給dist資料夾中chunk-vendors.js做splitChunks分包,從而減少首屏載入時間

chunk-vendors.js檔案太大了,所以我們需要將其優化一下,拆分一下

chunk-vendors.js是啥

chunk-vendors.js,顧名思義chunk(塊/包)-vendors(供應商),即為:不是自己寫的模組包,也就是/node_modules專案目錄的所有模組包。所以這個chunk-vendors.js檔案大的原因其實就是,我們把第三方的包都打包在這一個檔案上了,都糅在一塊,肯定大啊,所以想辦法把其做一個拆分。

使用optimization.splitChunks做分包

我們先看一下分包拆分以後打包的dist資料夾中的js檔案大小

分包以後的效果圖

專案效能優化之給dist資料夾中chunk-vendors.js做splitChunks分包,從而減少首屏載入時間

這樣的話,我們就把chunk-vendors.js檔案由,原來的824kB拆分成一個個幾十KB的包檔案了,這樣的話,生產環境載入的時候,就會快一些

splitChunks分包程式碼

我們以vue為例,在vue.config.js檔案中加入以下程式碼。程式碼大家直接複製貼上即可使用,也是筆者自己在生產環境中使用的哦。

    configureWebpack: config => {
        if (process.env.NODE_ENV !== 'production') return
        return {
            plugins: [
               // ......
            ],
            // 看這裡:把chunk-vendors.js進行分包,提升資源載入速度,很有必要
            optimization: {
                /**
                 * runtimeChunk可選值有:true或'multiple'或'single'
                 * true或'multiple'會有每個入口對應的chunk。不過一般情況下
                 * 考慮到要模組初始化,設定為single就夠多數情況下使用啦。
                 * 詳情見官網:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
                 * */
                runtimeChunk: 'single',
                /**
                 * 以前是CommonsChunkPlugin,現在換成optimization.splitChunks。普通專案下方的配置就足夠用啦
                 * 詳情見官網:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
                 * */
                splitChunks: {
                    chunks: 'all', // 可選值:all,async 和 initial。all功能最強大,所以我們們就使用all
                    maxInitialRequests: Infinity, // 最大並行請求數,為了以防萬一,設定無窮大即可
                    minSize: 20000, // 引入的模組大於20kb才做程式碼分割,官方預設20000,這裡不用修改了
                    maxSize: 60000, // 若引入的模組大於60kb,則告訴webpack嘗試再進行拆分
                    cacheGroups: {
                        vendors: {
                            test: /[\\/]node_modules[\\/]/, // 使用正則匹配node_modules中引入的模組
                            priority: -10, // 優先順序值越大優先順序越高,預設-10,不用修改
                            name(module) { // 設定分包以後的檔案模組名字,按照包名字替換拼接一下
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                                return `npm.${packageName.replace('@', '')}`
                            },
                        },
                    },
                }
            }
        }
    },

總結

好記性不如爛筆頭,記錄一下吧^_^

相關文章