淺談webpack優(yōu)化

移動端項目,需要嚴格控制包的大小,不然影響用戶體驗,所以需要對webpack進行優(yōu)化
本文檔主要介紹自己初次體驗webpack優(yōu)化的一些知識點。

敲黑板

包分析工具

vue-cli內(nèi)置包分析工具

// webpack.prod.conf.js
if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

可以通過在package.json添加命令開啟包分析工具,默認8888端口

"analyze": "NODE_ENV=production npm_config_report=true npm run build"

vue-cli 默認配置 打包思路

vue-cli默認配置將node_modules里的依賴都打進vendor中,有一些弊端

  • 引入的模塊越多,vendor文件越大
  • 提取公共文件目的是,一次打包,之后文件盡可能被瀏覽器緩存下來,不能每次打包都去改變hash值
  • 這個vendor文件將node_modules中所有依賴都進行抽離,之后維護如果添加新的模塊或者刪除一些沒有用的模塊,那么vendor的hash值會發(fā)生變化,不利于瀏覽器緩存

項目中,我主要通過CommonsChunkPlugin插件對webpack進行優(yōu)化,將本來1M的包,最后只有300+kb

CommonsChunkPlugin

  • 會將項目中引入的node_modules中的模塊抽離出來
new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function (module) {
    // this assumes your vendor imports exist in the node_modules directory
    return module.context && module.context.includes('node_modules');
  }
});
  • 提取公共模塊,如果沒有添加或者刪除公共模塊,則hash值不變,首次加載被瀏覽器緩存
  • 盡量將項目中不變的依賴包 抽離出一個文件,保證后續(xù)引入別的依賴包,此文件hash值不變化
  • 下圖中將vue vuex vue-router vant繼續(xù)抽離出一個文件

代碼如下,兩種寫法

// 方法一 對module.context進行過濾
new webpack.optimize.CommonsChunkPlugin({
    names: "common",
     minChunks: function(module, count) {
       if (module.resource && /^.*\.(css|scss)$/.test(module.resource)) {
         return false;
       }
       return module.context && 
         (module.context.includes("vue") ||
         module.context.includes("vant") ||
         module.context.includes("vuex") ||
         module.context.includes("vue-router"));
     }
   }),
// 方法二
// webpack.base.conf 文件  將公共模塊,寫入入口
entry: {
   app: './src/main.js',
   common: ['vue', 'vuex', 'vue-router', 'vant']
},
// webpack.prod.conf 
new webpack.optimize.CommonsChunkPlugin({
   name: 'common',
   minChunks: Infinity // 除了入口的模塊,其他模塊都不打包進入common
}),

修改router,目的修改打包之后的js文件,便于跟蹤

通過下面對每個路由進行修改,添加webpackChunkName,打包出來每個模塊的js名稱會根據(jù)自己設(shè)定的來
除此之外,還需要同步修改webpack.prod.conf.jsoutput的配置

output: {
   path: config.build.assetsRoot,
   filename: utils.assetsPath('js/[name].[chunkhash].js'),
   chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
 },
component: () => import(/* webpackChunkName: "home" */ '@/containers/home.vue'),
image.png

對minChunks理解

當entry屬性的值為對象時,作為多個入口的文件們,每個都是一個chunk

minChunks:number

某個模塊最少被多少個入口文件依賴,當大于等于設(shè)定的值,就會被打入公共包,小于這個值,該模塊就會被和每個入口打包在一起

minChunks:infinity

不會把任何依賴的模塊提取出來打入公共包

minChunks:默認值

如果沒有設(shè)置,則為默認值,只有被所有入口文件所依賴,則提取出來打公共包

代碼分割

  • 分離業(yè)務(wù)代碼和第三方庫 (vendor)
  • 按需加載 (利用路由中 import() 語法 component: () => import('@/components/Hello'))
  • 首頁首次加載的時候如果不需要就不加載,等加載到響應(yīng)路由再去加載相關(guān)資源
  • 減少首屏加載時間
  • 根據(jù)模塊的相對路徑生成一個四位數(shù)的hash作為模塊id
    • webpack里每個模塊都有一個module id
    • HashedModuleIdsPlugin 模塊根據(jù)相對路徑生成一個四位數(shù)hash作為模塊id,引入新的模塊,不影響module id,只要模塊路徑不改變
    • new webpack.HashedModuleIdsPlugin()

參考文章

webpack
commonsChunkPlugin
demo

希望此文對大家有幫助,歡迎吐槽

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容