vue首屏加載優化總結及整理

 

頁面加載性能是一個老生常談的問題,但是卻異常重要,尤其在訪問量大的商業軟件中。但是有很多開發者在開發過程中壓根就沒有考慮過這個問題。大家在開發業務代碼的過程中,也就忽略了這個增加工作量,也不會帶來什麼直觀的工作內容。


寫在前面,這裏以vue框架爲例,基於vue-cli3的開發方式

首先,使用webpack分析工具,查看當前項目的依賴,分析依賴及打包情況,對症下藥

安裝插件

npm i webpack-bundle-analyzer -D

在vue.config.js中,添加如下配置:

chainWebpack: (config)=>{
    /* 添加分析工具*/
    if (process.env.NODE_ENV === 'production') {
      if (process.env.npm_config_report) {
        config
          .plugin('webpack-bundle-analyzer')
          .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
          .end()
        config.plugins.delete('prefetch')
      }
    }

    ...
  }

執行命令

npm run build --report

執行成功後,瀏覽器會打開一個窗口,顯示當前依賴的大小及各打包文件情況

結合自己的項目情況,分析依賴的引入及打包情況,有以下幾點優化方式

第一,路由懶加載。

查看打包目錄中,js文件夾下的chunk-哈希值的文件爲採用懶加載形式時生成的文件,一個路由會生成一個文件。

const home= () => import('@/pages/home/index.vue')

第二,使用CDN引入第三方依賴。

比如,直接引入ehcarts會發現佔打包文件較大的空間,如果項目沒有特殊要求,可以採用CDN的方式引入;其他諸如axios、vue、lodash等都可以採用這種方式。

  • 在index.html中引入CDN資源
...
  <body>
    <div id="app">
    </div>
    <!-- built files will be auto injected -->
    <script src="//cdn.bootcss.com/echarts/4.2.1/echarts.simple.min.js"></script>
  </body>
  ...
  • 修改vue.config.js配置文件
module.exports = {
    configureWebpack: {
      externals: {
        'echarts': 'echarts' // 配置使用CDN
      }
    }
   }

externals中的key是用於import,value表示的在全局中訪問到該對象,就是window.echarts

在vue中使用echarts的時候無需 import echarts,可直接使用

第三,按需加載第三方類庫

比如,項目中使用了 lodash 庫,如果不是大量使用裏面的方法的話,可以這樣引入

import _cloneDeep from 'lodash/difference' // 或者 const _cloneDeep = require('lodash/difference')
const o = _cloneDeep ({a: 1, b: 2}) 

也可以藉助第三方插件的形式,lodash-webpack-plugin和babel-plugin-lodash。

在使用中還是採用原有的 import _ from 'lodash'方式,只是藉助插件,在打包時webpack會根據使用的方法按需打包

先安裝依賴

npm install lodash-webpack-plugin babel-plugin-lodash -D

上述插件可能部分已經存在於項目中,可以根據實際刪除

接着修改 vue.config.js


const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");

module.exports = {
  configureWebpack: config => {
     if (process.env.NODE_ENV === 'production') {
        return{
           plugins: [
              new LodashModuleReplacementPlugin(), //優化lodash
           ]
        }
     }
  }
};

附:使用 IgnorePlugin 插件優化 moment.js


const webpack = require('webpack');

module.exports = {
  configureWebpack: config => {
     if (process.env.NODE_ENV === 'production') {
        return{
           plugins: [
              new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 忽略/moment/locale下的所有文件
           ]
        }
     }
  }
};

按需引入 element-ui,參見官方文檔即可,其他組件庫類似

注:如果是按需一次性在main.js中引入,雖然比全部引入要小一些,但是也會一定程度上影響首次加載,這個看項目而行吧。

按需引入後element-ui小了很多,不過看到文章開頭的圖上顯眼的 table.js後想到, table組件只有後臺管理頁面用到了,不需要全局註冊,所以我們刪除 main.js中 Table和 TablColumn的引用,並在後臺組件中局部註冊。

這裏處理的思路就是,將按需引入處理到極致。如果是對首屏要求很高,可以採用這種方式,哪裏用到哪裏才引用,這其實也是平時開發中的一種良好習慣。

chunk.venders.js 。如果是文件爲第三方依賴的打包後文件,在做完這些優化之後,會發現這個文件有顯現的減小。

第四,打包時去掉sourceMap文件

修改 vue.config.js 配置

module.exports = {
  productionSourceMap: false
}

第五,將靜態資源使用cdn加載

將項目中的靜態資源js css等放在oss服務器或者其他地方,減小服務器壓力

第六,開啓 gzip壓縮

我在項目中啓用壓縮後,文件大小減少了70%以上,優化效果十分明顯。

下圖是在簡單做了部分優化之後的加載過程(優化開始時忘了截圖),耗時8s以上。服務器端配置以 nginx 爲例

如果 Nginx 服務器開啓 gzip,會將靜態資源在服務端進行壓縮,壓縮包傳輸給瀏覽器後,瀏覽器再進行解壓使用,這大大提高了網絡傳輸的效率,尤其對 js,css 這類文本的壓縮,效果很明顯。

客戶端

安裝依賴

npm i -D compression-webpack-plugin

修改 vue.config.js 配置

const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')

module.exports = {
 ...
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      return {
        plugins: [
          new CompressionPlugin({
            test: /\.js$|\.html$|\.css$|\.jpg$|\.jpeg$|\.png/, // 需要壓縮的文件類型
            threshold: 10240, // 歸檔需要進行壓縮的文件大小最小值,這裏是10K以上的進行壓縮
            deleteOriginalAssets: false // 是否刪除原文件
          })
        ]
      }
    }
  }
}

打包後,查看js文件

可以看到所有文件都被壓縮了三分之二以上

在服務器我們也要做相應的配置

# 開啓|關閉 gzip。
gzip on|off;
# 文件大於指定 size 才壓縮,以 kb 爲單位。
gzip_min_length 10;
# 壓縮級別,1-9,值越大壓縮比越大,但更加佔用 CPU,且壓縮效率越來越低。
gzip_comp_level 2;
# 壓縮的文件類型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;
# 開啓後如果能找到 .gz 文件,直接返回該文件,不會啓用服務端壓縮。
gzip_static on|off
# 是否添加響應頭 Vary: Accept-Encoding 建議開啓。
gzip_vary on;
# 請求壓縮的緩衝區數量和大小,以 4k 爲單位,32 爲倍數。
gzip_buffers 32 4K;

注:遇到服務端開啓gzip後,並沒有生效的問題,發現是nginx配置壓縮文件類型時 application/x-javascript,如果是這樣的寫法則並不會生效。

JavaScript的MIME類型通常爲“application/x-javascript”, 非IE的瀏覽器認“application/javascript”,

所以在上述配置中 application/javascript 和 application/x-javascript 並用,可以解決該問題。

然後重啓nginx服務

systemctl restart nginx.service

當在請求中出現如下標識,即開啓成功

再對比一下資源加載時間

前者爲啓用壓縮前,後者爲壓縮後,時間從8.33s減少到了2.44s,效率提高了70%以上

第七,冗餘代碼

打包文件 app.哈希.js 中爲所有vue文件打包的集合。

基於此,把項目中的冗餘代碼,註釋的多餘代碼刪除一通後,你會發現文件會變小。

可能人就是這樣,在項目中覺得多幾行css 多幾個標籤覺得不會對頁面產生什麼影響,但是如果做一通優化之後看到了‘數字性’的減少,纔會思考編寫高性能代碼對加載性能的影響。

第八,瀏覽器緩存

瀏覽器緩存可以分爲強緩存和協商緩存,根據實際應用場景來選擇緩存方式或者結合使用。一般來講一些基本不會變化的靜態資源文件可以設置強緩存,更新頻繁的文件不要設置緩存。而啓用緩存的好處在於,在某個時間段內可以減少發送請求的數量,從而使頁面響應更快,也就有更好的頁面體驗。

基本原理:瀏覽器緩存分強緩存和協商緩存,他們是將網絡資源存儲在本地,等待下次請求該資源時,如果命中就不需要到服務器重新請求該資源,直接在本地讀取該資源。

  • 強緩存:在web服務器返回的響應中添加Expires和Cache-Control Header
  • 協商緩存:通過【Last-Modified, If-Modified-Since】和【ETag, If-None-Match】兩對Header分別管理

關於緩存的詳細介紹,推薦一篇文章,時空隧道

好啦,文章提到的優化方式基本就是這些,當然優化也不至於此,還有網絡加載優化、頁面渲染優化(動畫、重排、重繪等)、瀏覽器文件緩存等等。如果有更好的優化方式歡迎評論。

寫在最後,頁面優化本身是一件很抽象的工作,但是我們卻可以通過平時的編碼規範來促成更可靠的頁面。優化的過程也是一個見仁見智的過程,要結合實際項目實際分析。優化的過程也會引發我們對於編碼時的一些思考,原來這樣寫對頁面加載會更友好,不知不覺中也能促進編寫高可用的能力。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章