淺談webpack優化

移動端項目,須要嚴格控制包的大小,否則影響用戶體驗,因此須要對webpack進行優化
本文檔主要介紹本身初次體驗webpack優化的一些知識點。css

敲黑板

包分析工具

便於分析哪些包有問題,哪些包體積過大等現象
vue-cli內置包分析工具vue

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

能夠經過在package.json添加命令開啓包分析工具,默認8888端口node

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

vue-cli 默認配置 打包思路

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

  • 引入的模塊越多,vendor文件越大
  • 提取公共文件目的是,一次打包,以後文件儘量被瀏覽器緩存下來,不能每次打包都去改變hash值
  • 這個vendor文件將node_modules中全部依賴都進行抽離,以後維護若是添加新的模塊或者刪除一些沒有用的模塊,那麼vendor的hash值會發生變化,不利於瀏覽器緩存

項目中,我主要經過CommonsChunkPlugin插件對webpack進行優化,將原本1M的包,最後只有300+kbweb

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值不變,首次加載被瀏覽器緩存
  • 儘可能將項目中不變的依賴包 抽離出一個文件,保證後續引入別的依賴包,此文件hash值不變化
  • 下圖中將vue vuex vue-router vant繼續抽離出一個文件

代碼以下,兩種寫法vue-router

// 方法一 對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名稱會根據本身設定的來
除此以外,還須要同步修改webpack.prod.conf.jsoutput的配置vuex

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屬性的值爲對象時,做爲多個入口的文件們,每一個都是一個chunkvue-cli

minChunks:number

某個模塊最少被多少個入口文件依賴,當大於等於設定的值,就會被打入公共包,小於這個值,該模塊就會被和每一個入口打包在一塊兒npm

minChunks:infinity

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

minChunks:默認值

若是沒有設置,則爲默認值,只有被全部入口文件所依賴,則提取出來打公共包

代碼分割

  • 分離業務代碼和第三方庫 (vendor)
  • 按需加載 (利用路由中 import() 語法 component: () => import('@/components/Hello'))

    • 首頁首次加載的時候若是不須要就不加載,等加載到響應路由再去加載相關資源
    • 減小首屏加載時間
  • 根據模塊的相對路徑生成一個四位數的hash做爲模塊id

    • webpack裏每一個模塊都有一個module id
    • HashedModuleIdsPlugin 模塊根據相對路徑生成一個四位數hash做爲模塊id,引入新的模塊,不影響module id,只要模塊路徑不改變
    • new webpack.HashedModuleIdsPlugin()

參考文章

webpack
commonsChunkPlugin
demo

但願此文對你們有幫助,歡迎吐槽

相關文章
相關標籤/搜索