在使用
elementUI
構建公司管理系統時,發現首屏載入時間長,載入的網路資源比較多,對系統的體驗性會差一點,而且用webpack
打包的vuejs的vendo
r包會比較大。所以通過蒐集網上所有對於vuejs
專案的效能優化,做了有關3方面的優化建議,主要包括:上線程式碼包打包、原始碼編寫優化、使用者體驗優化。(下面的優化建議只在vue-cli
腳手架下做過測試,詳情請參考)
1.程式碼包優化
遮蔽sourceMap
待下專案開發完成。進行打包原始碼上線環節,需要對專案開發環節的開發提示資訊以及錯誤資訊進行遮蔽,一方面可以減少上線程式碼包的大小;另一方面提高系統的安全性。在vuejs專案的config目錄下有三個檔案dev.env.js
(開發環境配置檔案)、prod.env.js
(上線配置檔案)、index.js
(通用配置檔案)。vue-cli腳手架在上線配置檔案會自動設定允許sourceMap
打包,所以在上線前可以遮蔽sourceMap。如下所示,index.js的配置如下,通用配置檔案分別對開發環境和上線環境做了打包配置分類,在build物件中的配置資訊中,productionSourceMap
修改成false
:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/ndindex.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: true,
productionGzipExtensions: ['js', 'css','svg'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
複製程式碼
對專案程式碼中的JS/CSS/SVG(*.ico)檔案進行gzip壓縮
在vue-cli腳手架的配置資訊中,有對程式碼進行壓縮的配置項,例如index.js
的通用配置,productionGzip
設定為true
,但是首先需要對compress-webpack-plugin
支援,所以需要通過 npm install --save-dev compression-webpack-plugin
(如果npm install
出錯了,就使用cnpm install
安裝。可能網路比較差npm install
會出現頻率比較大),gzip
會對js、css檔案進行壓縮處理;對於圖片進行壓縮問題,對於png,jpg,jpeg
沒有壓縮效果,對於svg,ico檔案以及bmp檔案壓縮效果達到50%,在productionGzipExtensions: ['js', 'css','svg']
設定需要進行壓縮的什麼格式的檔案。對專案檔案進行壓縮之後,需要瀏覽器客戶端支援gzip以及後端支援gzip。下面可以檢視成功支援gzip狀態:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/ndindex.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: true,
productionGzipExtensions: ['js', 'css','svg'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
複製程式碼
對路由元件進行懶載入
在路由配置檔案裡,這裡是router.js裡面引用元件。如果使用同步的方式載入元件,在首屏載入時會對網路資源載入載入比較多,資源比較大,載入速度比較慢。所以設定路由懶載入,按需載入會加速首屏渲染。在沒有對路由進行懶載入時,在Chrome裡devtool查閱可以看到首屏網路資源載入情況(6requests 3.8MB transfferred Finish:4.67s DOMContentLoaded 2.61s Load 2.70s)
。在對路由進行懶載入之後(7requests 800kb transffered Finish2.67s DOMContentLoaded 1.72s Load 800ms)
,可以看見載入速度明顯加快。但是進行懶載入之後,實現按需載入,那麼專案打包不會把所有js打包進app.[hash].js
裡面,優點是可以減少app.[hash].js
體積,缺點就是會把其它js分開打包,造成多個js檔案,會有多次https請求。如果專案比較大,需要注意懶載入的效果。
// 實現懶載入方式
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
export default new Router({
mode: "history",
base: "/facex/district/",
routes: [
{ path: "/", redirect: "index" },
{
path: "/",
name: "home",
component: resolve=>require(["@/views/home"],resolve),
children: [
{
// 員工查詢
path: "/employees",
component: resolve=>require(["@/components/employees"],resolve)
},
{
// 首頁
path: "/index",
component: resolve=>require(["@/views/index"],resolve)
},
{
// 訪客查詢
path: "/visitorlist",
component: resolve=>require(["@/components/visitorlist"],resolve)
},
{
path: "/department",
component: resolve=>require(["@/views/department"],resolve)
},
//識別查詢
{
path: "/discriminate",
component: resolve=>require(["@/components/discriminate"],resolve)
},
{
path: "/addDevice",
component: resolve=>require(["@/views/addDevice"],resolve)
},
{
path: "/districtNotice",
component: resolve=>require(["@/components/districtNotice"],resolve)
}
]
},
{
path: "/noticeList",
name: "noticeList",
component: resolve=>require(["@/views/noticeList"],resolve)
},
{
path: "/login",
name: "login",
component: resolve=>require(["@/views/login"],resolve)
},
{
path: "/register",
name: "register",
component: resolve=>require(["@/views/register"],resolve)
},
{
path: "/setaccount",
name: "setaccount",
component:resolve=>require(["@/views/setaccount"],resolve)
},
{
path: "/addGroup",
name: "addGroup",
component:resolve=>require(["@/views/addGroup"],resolve)
},
{
path: "/guide",
name: "guide",
component:resolve=>require(["@/components/guide"],resolve)
},
{
path: "/addNotice",
name: "addNotice",
component: resolve=>require(["@/views/addNotice"],resolve)
}
]
});i
複製程式碼
2.原始碼優化
v-if 和 v-show選擇呼叫
v-show和v-if的區別是:v-if是懶載入,當狀態為true時才會載入,並且為false時不會佔用佈局空間;v-show是無論狀態是true或者是false,都會進行渲染,並對佈局佔據空間對於在專案中,需要頻繁呼叫,不需要許可權的顯示隱藏,可以選擇使用v-show,可以減少系統的切換開銷。
為item設定唯一key值,
在列表資料進行遍歷渲染時,需要為每一項item設定唯一key值,方便vuejs內部機制精準找到該條列表資料。當state更新時,新的狀態值和舊的狀態值對比,較快地定位到diff。
細分vuejs元件
在專案開發過程之中,第一版本把所有的元件的佈局寫在一個元件中,當資料變更時,由於元件程式碼比較龐大,vuejs的資料驅動檢視更新比較慢,造成渲染比較慢。造成比較差的體驗效果。所以把元件細分,比如一個元件,可以把整個元件細分成輪播元件、列表元件、分頁元件等。
減少watch的資料
當元件某個資料變更後需要對應的state進行變更,就需要對另外的元件進行state進行變更。可以使用watch監聽相應的資料變更並繫結事件。當watch的資料比較小,效能消耗不明顯。當資料變大,系統會出現卡頓,所以減少watch的資料。其它不同的元件的state雙向繫結,可以採用事件中央匯流排或者vuex進行資料的變更操作。
內容類系統的圖片資源按需載入
對於內容類系統的圖片按需載入,如果出現圖片載入比較多,可以先使用v-lazy之類的懶載入庫或者繫結滑鼠的scroll事件,滾動到可視區域先再對資料進行載入顯示,減少系統載入的資料。
SSR(服務端渲染)
如果專案比較大,首屏無論怎麼做優化,都出現閃屏或者一陣黑屏的情況。可以考慮使用SSR(服務端渲染),vuejs官方文件提供next.js很好的服務端解決方案,但是侷限性就是目前僅支援Koa、express等Nodejs的後臺框架,需要webpack支援。目前自己瞭解的就是後端支援方面,vuejs的後端渲染支援php,其它的不太清楚。
3.使用者體驗優化
better-click防止iphone點選延遲
在開發移動端vuejs專案時,手指觸控時會出現300ms的延遲效果,可以採用better-click對ipone系列的相容體驗優化。
菊花loading
菊花loading,在載入資源過程之中,可以提供loading。此菊花loading不是那菊花。所以可以自由選擇自己喜歡的菊花。
骨架屏載入
在首屏載入資源較多,可能會出現白屏和閃屏的情況。體驗不好。盜圖一波,小米商城使用骨架屏進行首屏在資源資料還沒有載入完成時顯示,給很好的體驗效果。
參考文章:
Vue頁面骨架屏的實現方法
淺談 Vue 專案優化
Vue 初始化效能優化
Vue 效能優化經驗總結
路由懶載入
VUE2元件懶載入淺析
基於VUE的SPA單頁應用開發-載入效能篇