第一次打包vue的項目部署到服務器,發現首次加載特別的緩慢要幾十秒才加載出來,完全沒有在本地開發環境上那么流暢。主要原因是頁面在打包后沒有進行相關的配置導致資源文件特別大,一次想要全部加載完成回特別的耗時。
下面是總結的vue項目性能優化的方案
一:vue-router 路由 懶加載
在使用同步的方式加載組件的時候,首屏加載會對網絡資源加載比較多,資源比較大,加載速度比較慢,所以設置路由懶加載,按需加載會加速首屏的渲染。但是在設置懶加載之后,實現按需加載,那么項目打包不會把所有js打包進app.js里面,有點是減少app.js體積,缺點就是會把其他js分開打包,造成多個js文件,會有多次http請求。若項目比較大,需要注意懶加載的效果。按需加載之后,除了公共文件,會把每個頁面獨有的樣式和腳本都打包成一個單獨的文件,這樣除了公共文件外,訪問一個頁面只會加載改頁面所需要的文件即可,這會大大減少首屏頁面的壓力
1是同步加載,頁面加載就全部導入
2和3是異步加載,使用該組件的時候才會請求(懶加載)
component: () => import('url'); // 這個是懶加載
component: resolve => (require(['url'], resolve));// 這個是按需加載,
二:代碼包的優化,
1.去掉編譯文件中map文件
在編譯好后,經常會有特別多的.map文件,這些主要是幫助我們線上調試代碼用的,為了避免部署包過大,通常都不生成這些文件。在config配置中將productionSourceMap的值設置為false。再次打包就沒有.map文件了。
2.對項目代碼中的JS/CSS/SVG(*.ico)文件進行gzip壓縮
gzip會對js、css文件進行壓縮處理(壓縮效果明顯,能壓縮至原來的1/3左右);對於圖片進行壓縮問題,對於png、jpg、jpeg沒有壓縮效果,對於svg,ico文件以及bmp文件壓縮效果達到1/2,在productionGzipExtensions: ['js', 'css', 'svg']設置需要進行壓縮的什么格式的文件。
在config中配置如下圖
當然,這只是開啟了gzip壓縮開關,還需要安裝compress-webpack-plugin插件進行支持
npm i --save-dev compression-webpack-plugin
三:合理使用vue的指令
1.v-if 和 v-show 的合理使用
2.使用v-for的時候為item設置唯一key值
3.細分vuejs組件
在項目開發過程中第一版本把所有的組件的布局寫在一個組件中,當數據變更時,由於組件代碼比較龐大,vuejs的數據驅動視圖更新比較慢,造成渲染比較慢。體驗效果比較差,所以把組件細分,比如一個組件,可以把整個組件細分成輪播組件、列表組件、分頁組件等
4.減少watch的數據
當組件某個數據變更后,需要對應的state進行變更,就需要對另外的組件進行state進行變更。可以使用watch監聽相應的數據變更並綁定事件。當watch的數據比較小,性能消耗不明顯。當數據變大,系統會出現卡頓,所以減少watch的數據。其他不同的組件的state雙向綁定,可以采用事件中央總線或者vuex進行數據變更操作
5.內容類系統的圖片資源按需加載
對於內容類系統的圖片按需加載,如果出現圖片加載比較多,可以先試用v-lazy之類的懶加載庫或者綁定鼠標的scroll事件滾動到可視區域再對數據進行加載顯示,減少系統加載的數據。
6.SSR(服務端渲染)
如果項目比較大,首屏無論怎么做優化,都出現閃屏或者一陣黑屏的情況。可以考慮使用SSR(服務端渲染),vuejs官方文檔提供next.js很好的服務端解決方案,但是局限性就是目前僅支持Koa.express等Nodejs的后台框架,需要webpack支持。
四:使用CDN
1.為什么使用CDN
使用CDN主要解決兩個問題:
① 打包時間太長、打包后代碼體積太大、請求慢
② 服務器網絡不穩定帶寬不高,使用cdn刻意回避服務器貸款問題
2.具體步驟
在index.html中引入CDN
注意:修改配置后還是提示element未定義,是因為element依賴Vue,vue.js需要在element-ui之前引入,所以vue.js也要改為cdn的引入方式修改/build/webpack.base.conf.js中修改配置。給module.exports添加externals屬性(詳見https://webpack.docschina.org/configuration/externals/),其中鍵是項目中引用的,值是所引用資源的名字。需要注意的是資源名需要查看所引用的JS源碼,查看其中的全局變量是什么,
例如element-ui的全局變量就說ELEMENT
刪除原先的import
如果不刪除原先的import
,項目還是會從node_modules
中引入資源。
也就是說不刪的話,npm run build
時候仍會將引用的資源一起打包,生成文件會大不少。所以我認為還是刪了好。
五、webpack打包時使用gzip壓縮
安裝 compression-webpack-plugin
npm install compression-webpack-plugin --save-dev
配置vue.config.js文件
const CompressionPlugin = require('compression-webpack-plugin'); module.exports = { publicPath: '/', assetsDir: 'static', outputDir: process.env.OUTPUT_DIR, productionSourceMap: false, configureWebpack: { plugins: [ new CompressionPlugin({ test: /\.(js|css)?$/i, // 哪些文件要壓縮 filename: '[path].gz[query]', // 壓縮后的文件名 algorithm: 'gzip', // 使用gzip壓縮 minRatio: 1, // 壓縮率小於1才會壓縮 deleteOriginalAssets: true // 刪除未壓縮的文件,謹慎設置,如果希望提供非gzip的資源,可不設置或者設置為false }) ] } };
配置完成之后打包會發現文件都變成.gz
然后在nginx服務器配置一下靜態壓縮
gzip on; gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css; gzip_static on;
gzip_static 設置為on之后,這樣就在訪問資源的時候,如果存在 .gz 文件,則會直接返回該文件,其優先級高於動態gzip,