記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)

zysallen發表於2018-05-19

原文在這裡,如果對你有幫助的話,動動你的小手手給個星星呀

注意:本文有點標題黨了,圖很多很羅嗦,不想看圖的同學可以直接看加粗的內容和最後的總結

第一次在掘金寫文章,哪裡有不對的地方或者更好的方案請不要給我面子,馬上提出來

最近在做一個專案,技術棧為vue全家桶 + element-ui + echarts,打包後發現有1.44M,首屏體驗很差。這能忍?果斷開始優化。下面說說我是如何將一個打包後1.44MB的專案變成打包後只有0.42MB,效能提升70% 的。

優化過程

  1. 準備:

    vue-cli提供了一個很方便的檢視程式碼打包後體積的命令,只需在正常的打包命令後加一個--report即可,這樣打包完成後會自動開啟一個頁面,展示各個依賴包的大小。

    npm run build --report
    複製程式碼
  2. 優化前:

    先看看優化前的大小吧

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    這是打包前本地localhost中首屏載入的js檔案,只有一個app.js3.2MB)(注意是本地,未打包,未壓縮)

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    這是打包後的截圖,體積為1.44MB,打包時間為72s

  3. 第一次優化:路由懶載入

    說到優化,第一個肯定考慮的是懶載入啦,馬上在vue和vue-router的官方文件裡找到了解決方案

    結合 Vue 的非同步元件和 Webpack 的程式碼分割功能,輕鬆實現路由元件的懶載入

    具體做法的話如下:

    首先要安裝一個外掛Syntax Dynamic Import使專案支援動態import

    cnpm install -S babel-plugin-syntax-dynamic-import
    複製程式碼

    然後修改.babelrc檔案

    // .babelrc 中的plugins陣列中多加一個"syntax-dynamic-import"
    {
      "plugins": ["syntax-dynamic-import"]
    }
    複製程式碼

    最後修改router.js,將所有路由都改為動態載入

    //router.js
    
    //原來的寫法:import Home from '@/components/PC/Home'
    //改成下面這種形式(其他路由同理)
    const Home = () => import('@/components/PC/Home')       
    複製程式碼

    OK,第一次優化完成。讓我們打包看看結果如何吧。

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)

    上面兩張圖分別是本地打包前首屏載入的js資源(經計算大約為3.1MB)的截圖和打包後的截圖(1.44MB),打包時間為 55s。注意我紅色框出來的部分,和優化前相比較打包的結果多了幾個以0 1 等數字開頭的js檔案,這其實就是我們的路由檔案被分離了出來,首屏只載入了需要的0.js3.js檔案,等到我們切換到其他路由的時候才會載入其他的2.js或者4.js,而不是像以前那樣全部包含在了app.js中一次性全載入出來。

    和優化前相比,打包後大小沒變,但是打包時間減少了,首屏載入的js資源也少了0.1MB(坑爹麼不是!!)。

    打包體積沒變,首屏才少了0.1MB?效果這麼差,你特麼在逗我?

    彆著急打我,聽我解釋。打包體積沒變是因為不管路由怎麼懶載入,實質上需要的路由檔案還是那麼多,大小是不變的,所以體積沒變。而首屏才少了0.1MB,是因為這個專案本來就是個很小的專案,只有4個頁面,而且這個專案的首頁引入了echarts本來就相對來說比較大。

    所以說這一步路由懶載入的優化是完全ok的,效果不好是因為是我專案的原因,少了的那0.1MB是剩餘未載入的路由檔案大小。

    如果你的專案有很多個頁面,那麼路由懶載入的效果應該會不差。

    我們再次看看這個圖

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    發現左邊黃色的框echarts和右邊藍色的框element-ui體積佔了大頭,我們先看element-ui佔了556KB,現在開始針對element-ui進行第二次優化

  4. 第二次優化:element-ui元件按需載入

    針對element-ui的優化,沒啥好說的,具體做法,直接看文件裡面的按需引入吧。 照著文件優化了以後,再次打包檢視結果:

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)

    這次優化後,打包用了45s,總大小由1.44MB變成了1.16MB

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    而且element-ui模組所佔的大小也由556kb變成了267kb,效果還行。但是這點提升怎麼滿足的了我?解決了element-ui,我們看看另外一個模組echarts:

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    element-ui還要過分!!足足佔了606kb,馬上針對最大的boss----echarts進行優化。

  5. 第三次優化:使用 CDN 外部載入資源

    這次優化主要是針對echarts,在其文件裡也有提到按需載入,但是這次我們不用按需載入了,我想把echarts徹底幹掉!我們這次要使用webpackexternals參考這裡

    防止將某些 import 的包(package)打包到 bundle 中,而是在執行時(runtime)再去從外部獲取這些擴充套件依賴(external dependencies)。具有外部依賴(external dependency)的 bundle 可以在各種模組上下文(module context)中使用,例如 CommonJS, AMD, 全域性變數和 ES2015 模組。

    具體做法:

    首先在index.html中引入echarts的外部CDN(如果需要地圖元件,也需要一併引入)

    //index.html
    <script src="https://cdn.bootcss.com/echarts/4.1.0/echarts.min.js"></script>
    複製程式碼

    然後在webpack.base.config.js中,做如下改動

    //webpack.base.config.js   module.exports中增加externals物件
    module.exports = {
        externals: {
            "echarts": "echarts"        //預設是配置引用的庫(這裡是echarts)暴露出的全域性變數
        },
    }
    複製程式碼

    檢視優化結果:

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    這是打包前的本地首屏載入資源的截圖,可算出這次一共載入了1.31MB(沒有算上echarts.min.js,因為那是CDN資源),相對於第一次優化後的3.1MB已經少了很多了。

    打包後的截圖如下

    記一次vue+element+echarts專案的優化(如何輕鬆將專案效能提升70%)
    可以看到打包後的體積只有434.7KB,而且這次打包只花了34s,最重要的是echarts也真的被幹掉了!!

    驚不驚喜!!意不意外!!

    各次優化的表格

    懶得看圖的同學可以直接看下面這張表格

    # 打包後體積 壓縮後體積 首屏js資源 打包耗時
    優化前 1.44M 425K 3.2M 72s
    第一次優化(路由懶載入) 1.44M 434K 3.11M 55s
    第二次優化(element-ui按需載入) 1.16M 381K 1.3M 45s
    第三次優化(引入外部CDN) 434K 121K 1.3M 34s

    可以看出,我們的優化還是很有成效的,各種體積和打包耗時差不多減少了70% 左右。

    總結

    這部分一定要看啊啊啊

    • 遇到webpack打包效能問題,先執行npm run build --report分析一波,然後根據分析結果來做相應的優化,誰佔體積大就幹誰
    • 路由很多的複雜頁面,路由懶載入是肯定要做的
    • 現在很多庫都有提供按需載入的功能,有需要的話可以按照官方文件的做法來按需載入
    • webpack提供的externals可以配合外部資源CDN輕鬆大幅度減少打包體積,適用於echartsjQuerylodash這種暴露了一個全域性變數的庫
    • 千萬不要忘了開啟Gzip壓縮
    • 本文講的只是針對於webpack層面的優化,效能優化不只這些,還有其他方面的優化,比如頁面渲染優化(減少重排)網路載入優化等。
    • 本文的內容只適用於瀏覽器環境

相關文章