Vue-cli3.0的打包效能優化方案

小綠和小藍發表於2019-08-01

Vue-cli3.0的打包效能優化方案

專案背景

  1. 專案模板使用的是基於Vue-cli3的vue-admin-template
  2. 專案是單頁後臺
  3. 專案屬於中小型專案

問題 - 首屏載入非常慢

讓我們看看沒任何處理的測試包

Vue-cli3.0的打包效能優化方案

首屏載入竟然需要5-10s的載入時間! 這肯定是不符合線上要求的

分析一下載入的資源,明確發現以下問題

  1. elementUI的js檔案太大了,嚴重影響速度
  2. 整體程式碼未壓縮
  3. 某張圖片,靜態資源過大,應減小該圖片體積,或者優化靜態資源載入速度

如何優化

前端開啟gzip

關於這一點作者文件中分析構建檔案體積有提到,但是卻沒有給出解決方案,配置如下

伺服器開啟nginx後,程式碼經過壓縮就會小很多,但是如果我們打包後的程式碼沒有壓縮過,那就是服務端來負責壓縮,自然會拖慢服務端載入速度,我們應該在webpack中開啟壓縮

生成壓縮程式碼的webpack外掛

npm install compression-webpack-plugin -D
複製程式碼

修改vue.config.js

該物件將會被 webpack-merge 合併入最終的 webpack 配置。具體請看webpack相關

configureWebpack: config => {
    const baseConfig = {
        name: name,
        resolve: {
            alias: {
                '@': resolve('src')
            }
        }
    }
    if (process.env.NODE_ENV === 'production') {
        return {
            plugins: [
                // 壓縮程式碼
                new CompressionPlugin({
                    test: /\.js$|\.html$|.\css/, // 匹配檔名
                    threshold: 10240, // 對超過10k的資料壓縮
                    deleteOriginalAssets: false // true 不刪除原始檔 false 刪除原始檔
                })
            ],
            ...baseConfig
        }
    } else {
        return { ...baseConfig }
    }
}
複製程式碼

配置完成後再次打包程式碼,就會發現js資料夾裡面多出了 .js.gz檔案,那就是壓縮後的js程式碼

首頁圖進行優化

關於圖片部分,因為這個後臺僅僅有一張登入背景圖很大,所以對於小專案,只要將png圖片轉成jpg圖片即可所以大量的圖片體積,這個交給ui來完成

去除console.log與警告

注意: 去除警告現在為外掛 TerserWebpackPlugin webpack-parallel-uglify-plugin不在提供去除log與警告功能

該外掛的配置 minify-options

線上專案自然不應該被看到控制檯的列印日誌,所以我們需要將console.log都去除掉

npm install compression-webpack-plugin -D
複製程式碼

修改vue.config.js configureWebpack部分

configureWebpack: config => {
    const baseConfig = {
        name: name,
        resolve: {
            alias: {
                '@': resolve('src')
            }
        }
    }
    if (process.env.NODE_ENV === 'production') {
        return {
            plugins: [
                // 壓縮程式碼
                new CompressionPlugin({
                    test: /\.js$|\.html$|.\css/, // 匹配檔名
                    threshold: 10240, // 對超過10k的資料壓縮
                    deleteOriginalAssets: false // 不刪除原始檔
                }),
                // 去除console.log
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            warnings: false,
                            drop_console: true,
                            drop_debugger: true,
                            pure_funcs: ['console.log']
                        }
                    }
                })
            ],
            ...baseConfig
        }
    } else {
        return { ...baseConfig }
    }
}
複製程式碼

將elementUI改為按需載入

這一塊官方坑比較大,花了比較久的時間

安裝按需引入外掛

npm install babel-plugin-component -D
複製程式碼

配置

這裡因為babel的升級,按element官方配置,會報錯,presets部分增加會報錯

module.exports = {
  presets: ['@vue/app'],
  plugins: [
    [
      'component',
      {
        libraryName: 'element-ui',
        styleLibraryName: 'theme-chalk'
      }
    ]
  ]
}
複製程式碼

然後我們開始修改main.js裡面的按需引入程式碼

程式碼來自官方文件https://element.eleme.cn/#/zh-CN/component/quickstart#an-xu-yin-ru

import {
  Pagination,
  Dialog,
  Autocomplete,
  ....
} from 'element-ui'

Vue.use(Pagination)
Vue.use(Dialog)
Vue.use(Autocomplete)
.....

Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;
複製程式碼

這裡重啟專案,會報錯

img

google了很久,終於找到了類似問題

Uncaught ReferenceError: _MessageBox is not defined,沒解決方案elementUI非常棒,作為開發者非常感謝維護者大大們,但是麻煩官方也把出現的問題解決一下啊,這個issue多久了,還是去年的,一點回復都沒有,官方案例又跑不通,同時社群形同虛設,隔壁Antd的gitter,線上聊天室維護者會回覆問題,Taro社群有微信群,element的gitter就和只是用來聊天的gitter,全都是問題,卻沒有答案,這樣真的不好

問題解決

element改為按需引入後會報錯,來自vue-element-admin的issues,問題提出者的解決方案

Vue-cli3.0的打包效能優化方案

親測可用

import {
  Pagination,
  Dialog,
  Autocomplete,
  ....
} from 'element-ui'

Vue.use(Pagination)
Vue.use(Dialog)
Vue.use(Autocomplete)
.....

Vue.prototype.$msgbox = MessageBox
Vue.prototype.$alert = Vue.prototype.$msgbox.alert
Vue.prototype.$confirm = Vue.prototype.$msgbox.confirm
Vue.prototype.$prompt = Vue.prototype.$msgbox.prompt
Vue.prototype.$message = Message
複製程式碼

優化後

最後來看一下,優化後,專案啟動速度是多久

  • element的js包由638kb減小為110kb
  • 圖片改為jpg格式,不降低質量的情況下 422kb減小到253kb
  • 整體程式碼包體積減小了50%

在模擬3g網路下,頁面第一次進入3s就會基本完成了全部載入

Vue-cli3.0的打包效能優化方案

模擬4g網速的情況下,1s完成頁面的載入

Vue-cli3.0的打包效能優化方案

小結

關於Vue打包檔案使用靜態sdn來減小專案體積,個人而言不太贊同,畢竟靜態cdn是別人的東西,假如cdn掉線了,專案出現問題,責任誰都承擔不起

本文是比較淺層的優化,專案依舊可以繼續優化,但是提升效果可能不太明顯

但是經過上面的步驟,基本滿足大部分專案的需求,可以達到自己想要的效果

相關文章