Vue包大小優化的實現(從1.72M到94K)
一、背景
最近做瞭一個網站,uidea,是用來輔助獨立開發者做一些 UI 設計的,當時隻管開發,等部署完以後,發現訪問速度堪憂
畢竟是個小水管服務器,相比提高帶寬,還是先看看代碼上能不能優化一下,性價比更高
這個是優化前的包大小,這傢夥都上 1.72 M 瞭,小水管加載時間直接往 3s 以上走瞭,臣妾扛不住啊
二、目標
這必須得優化一下,優化前得大致定一下目標,目標又需要指標來衡量,所以定瞭兩個指標:
- 頁面加載時間不多說,至少得 1s 以內,越快越好
- 包大小控制在 200k 以內
為什麼定這兩個目標呢?首先頁面加載時間是最終要解決的問題,那頁面加載時間初步來看,影響因素有兩個,網絡和包大小,網絡暫時缺錢沒法升級,所以主要優化就集中在包大小上
首先要定義什麼是包大小,我這裡主要指入口包大小,對應 Vue 就是 app.js 和 app.css,入口加載完頁面至少可以展示瞭
那包大小要優化到什麼程度呢?
一方面 vue-cli-service 建議不超過 244K,另一方面就是找對標,看看類似的網站包大小多少,那我們也有個參照,我選擇的是 materialpalette,看瞭下他的包大小大概在 150k 左右,我的功能更復雜一些,所以取瞭兩者中間的 200K 作為目標
這裡為什麼要講目標呢?因為目標其實是很重要的,老話也說有的放矢,沒有目標,那執行的過程中很容易半途而廢,或者隻前進半步就終止瞭
拿談戀愛來說,如果你的目標是找個女朋友,那大概率找不到,但是如果你的目標是追到某個確定的女生(比如張三)做女朋友,那成功的概率就大大增加瞭,因為你可以去針對這個女生去做針對性的準備
三、方案
目標定瞭,然後就是定方案
雖然咱第一次做 Web 的優化,但是之前有過安卓包大小優化的經驗呀,道理總是相通的,所以第一時間想瞭下面幾個策略
- 代碼混淆
- 資源放到 cdn,因為開發的時候圖省事,資源放在 assets 下面,直接 require 引入瞭,這也是一個大頭
- 無用庫刪除,功能相近的庫合並,隻用到少部分功能的庫,看看能否自己實現
- gzip 壓縮
- 第三方庫也放到 cdn
1 – 3 三個優化方案是首先想到的,然後網上搜瞭下 Vue 對應的優化策略,又增加瞭後面兩個
還有一些其他方案,比如路由懶加載,但是因為這個網站主要內容都集中在首頁,所以這個就沒考慮瞭(好東西雖多,但因地制宜最好)
所以一共定瞭 5 個優化策略,下面就開幹
四、執行
1. 代碼混淆
代碼混淆就不多說瞭,一方面節省包大小,一方面還能增加一些反編譯的難度,直接網上搜瞭 Vue 混淆配置(畢竟要站在巨人肩膀上),試瞭下確實好使,配置如下
const CompressionWebpackPlugin = require('compression-webpack-plugin'); module.exports = { configureWebpack: (config) => { // 引入uglifyjs-webpack-plugin let UglifyPlugin = require('uglifyjs-webpack-plugin'); if (process.env.NODE_ENV == 'production') { // 壓縮混淆 config.mode = 'production' // 將每個依賴包打包成單獨的js文件 let optimization = { minimizer: [new UglifyPlugin({ uglifyOptions: { warnings: false, compress: { drop_console: true, drop_debugger: false, pure_funcs: ['console.log'] } } })] } Object.assign(config, { optimization }) } else { // 為開發環境修改配置 config.mode = 'development' } } } }
2. 資源放到 cdn
這一步也容易做,資源全部都放到阿裡雲 oss 上,幾分鐘搞定
3. 無用庫刪除
這一步花瞭不少時間,因為開發的時候圖省事,很多庫直接 github 上一搜,yarn add 引入就完事瞭,現在需要細細的再拆分一下
在打包命令後面加 –report 看一下打包的狀態
yarn build --report
首先是去掉 ElementUi(gzip 壓縮後大約 158k),開發的時候 ElementUi 和 Vuetify 混用瞭,其實隻留一個 Vuetify 就夠瞭,然後對界面做一些小小的改造就完成瞭
然後是 lodash,隻用到瞭其中幾個方法,但是他的整個體積不小,gzip 壓縮後大概 25k,於是找瞭 lodash 源碼,打算把用到的幾個方法抽出來,但是 lodash 代碼嵌套、引用太深瞭,不太抽,幹脆直接幹掉這個庫,找瞭幾個更純粹的實現做瞭替換,主要時間花在瞭讀 lodash 源碼上
再然後就是 vuescroll,在實現滾動條樣式自定義的時候,偷懶直接用瞭這個庫,發現這個庫體積還是不小的,gzip 壓縮後將近 20k,直接幹掉,自己寫一下樣式吧(這件事告訴我們,現在偷的懶,以後會以別的方式還回來的 0_0)
這樣就幹掉瞭幾個大頭庫
4. gzip 壓縮
這個是網上找的解決方案,直接在 vue.config.js 裡加點配置,然後 nginx 裡也需要做一下對應的配置
// vue.config.js module.exports = { configureWebpack: (config) => { if (process.env.NODE_ENV == 'production') { // ... // gzip config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.js$|\.html$|\.json$|\.css/, threshold: 10240, minRatio: 0.8 })) } // ... } } // nginx 直接開啟下面的配置 gzip_static on;
這樣打包以後,會生成 .gz 文件,nginx 會自動使用 .gz 文件
5. 第三方庫放到 cdn
這裡主要是處理 Vuetify 這個庫,畢竟 gzip 以後也有將近 50k 的大小,放到 cdn 上會快一些
首先是打包配置中去掉 Vuetify
module.exports = { // ... configureWebpack: (config) => { if (process.env.NODE_ENV == 'production') { // 第三方庫不打包,使用 cdn config.externals = { vuetify: 'Vuetify' } } else { // 為開發環境修改配置 config.mode = 'development' config.externals = { vuetify: 'Vuetify' } } } }
然後在 index.html 裡手動加載 vuetify css 和 js
<link href="https://cdn.staticfile.org/vuetify/2.4.4/vuetify.min.css" rel="external nofollow" rel="stylesheet"> <script src="https://cdn.staticfile.org/vuetify/2.4.4/vuetify.min.js"></script>
這裡其實有一些更好的方式,可以通過 webpack 參數傳給 index.html,通過 ejs 引入,現在比較簡單,這裡就沒做瞭
五、效果
通過上面幾個策略,最終包大小從 1.72 M 優化到 94k
六、後續
總體看來,優化效果是明顯的,但是還有後續可以做的事情:
- 更精細化優化,應該可以結合 webpack 做更深的定制化
- 對上面說到的 cdn 上的第三方庫做整合,畢竟直接放在 index.html 裡太散,並不是很好的項目結構,也不利於後面開發
- 對後續的代碼開發做規范,比如三方庫引用的規范、資源的引入規范等等,可以做的事情還是很多的
- 每次部署前的性能測試,主要看看頁面加載速度是否達標
可以做的事情還很多,有時候做一件事,達成目標並沒有結束,維持目標也是需要考慮的
到此這篇關於Vue包大小優化的實現(從1.72M到94K)的文章就介紹到這瞭,更多相關Vue包大小優化內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Vue項目打包、合並及壓縮優化網頁響應速度
- vue終極性能優化方案(解決首頁加載慢問題)
- 解決vue頁面刷新產生白屏的問題
- vue中的vendor.js文件過大問題及解決
- 如何設置process.env.NODE_ENV生產環境模式