webpack打包效能優化之路

rocky191發表於2019-01-12

效能優化的路沒有窮盡,只有更快。開啟頁面越快越好,點選響應越快越好。在當今這個以快為主的時代,快才是王道。閒話扯完,說正事!!!

該優化方案以最近做的一個hybrid webapp為例項演示。

路由懶載入

(1)vue-router檔案中的router使用懶載入方式。如下圖所示

webpack打包效能優化之路

(2)在vue檔案中,也採用類似方式引入其他vue元件

const showImage = () => import('@/components/common/showImage');
複製程式碼

這個優化的方式在vue官網也有介紹,傳送門

啟用gzip壓縮和關閉sourcemap

所有現代瀏覽器都支援 gzip 壓縮並會為所有 HTTP 請求自動協商此類壓縮。啟用 gzip 壓縮可大幅縮減所傳輸的響應的大小(最多可縮減90%),從而顯著縮短下載相應資源所需的時間、減少客戶端的流量消耗並加快網頁的首次呈現速度。 如下圖所示

webpack打包效能優化之路
如果你使用的是vue-cli2生成的專案的話,在config資料夾下的index.js中可以找到這段程式碼。記得開啟gzip壓縮前要安裝一個外掛,如途中註釋掉的一段程式碼所示。

生產環境去掉console程式碼,減少程式碼體積,使用uglifyjs壓縮程式碼

webpack打包效能優化之路

圖片優化

對於網頁來說,在所下載的位元組數中,圖片往往會佔很大比例。因此,優化圖片通常可以卓有成效地減少位元組數和改進效能:瀏覽器需要下載的位元組數越少,對客戶端頻寬的爭用就越少,瀏覽器下載內容並在螢幕上呈現內容的速度就越快。
儘量減少圖片的使用,或者使用css3來代替圖片效果。如果不行的話,小圖片通過一定的工具合成雪碧圖或者轉成base64。

引用的庫儘量按需載入。

(1)像一般的ui庫element,vant等庫都提供來按需載入的方式,避免全部引入,加大專案體積。 (2)以cdn方式載入需要的庫,也可以減少打包後的體積。 在index.html檔案中

引入mintui

<!-- 引入樣式 -->
<link rel="stylesheet" href="https://unpkg.com/mint-ui/lib/style.css">
<!-- 引入元件庫 -->
<script src="https://unpkg.com/mint-ui/lib/index.js"></script>
複製程式碼

引入vue

<!-- 開發環境使用此方案-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<!-- 生產環境使用此方案 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
複製程式碼

以這種外鏈方式引入mint-ui和vue後,需要做些別的配置
(1)在入口檔案main.js 中就不需要引入vue和mintui了
(2)在build\webpack.base.conf.js中新增如下配置,意為打包的時候不打包vue和mint-ui。

externals:{
  "mint-ui":"mintui",
  "vue":"Vue"
},
複製程式碼

使用DllReferencePlugin

將平時不經常變動的檔案抽離出來,統一打包,這樣也可以減少後續打包的時間。

  • 在build資料夾中新建一個webpack.dll.conf.js.
const path = require('path')
const webpack = require('webpack')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
  entry: {
    vendor: [
        //根據實際情況新增
      'axios',
      'vue/dist/vue.min.js',
      'vue-router',
      'vuex',
      'mint-ui'
    ]
  },
  output: {
    path: path.resolve(__dirname, '../static/js'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules\/(?!(autotrack|dom-utils))/
      }
    ]
  },
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: false // set to true if you want JS source maps
      }),
      // Compress extracted CSS. We are using this plugin so that possible
      // duplicated CSS from different components can be deduped.
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  plugins: [
    /*
      @desc: https://webpack.js.org/plugins/module-concatenation-plugin/
      "作用域提升(scope hoisting)",使程式碼體積更小[函式申明會產生大量程式碼](#webpack3)
    */
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'),
      name: '[name]_library'
    })
  ]
}

複製程式碼
  • 在package.json中增加配置
"scripts": {
    "build:dll": "webpack -p --progress --config build/webpack.dll.conf.js"
  }
複製程式碼

執行npm run build:dll命令就可以在根目錄下生成vendor-manifest.json,static/js下生成vendor.dll.js

  • 在webpack.base.conf.js中增加如下
const manifest = require('../vendor-manifest.json')

....

plugins: [
   //把dll的vendor-manifest.json引用到需要的預編譯的依賴
   new webpack.DllReferencePlugin({
     manifest
   })
]
複製程式碼
  • 在index.html底部新增
<script src="./static/js/vendor.dll.js"></script>
複製程式碼

目前在專案中做的優化就是這些,還是那句話,效能優化的路沒有窮盡,只有更快。

參考文章

(1)blog.csdn.net/blueberry_l…
(2)developers.google.com/speed/docs/…
(3)www.jeffjade.com/2017/03/11/…

相關文章