- 注:本文只適用于 vue-cli 初始化的項目或依賴于 webpack 打包的項目 *
首屏加載優(yōu)化
背景:基于vue-cli3創(chuàng)建的項目編譯后發(fā)布測試关划,發(fā)現(xiàn)有個文件chunk-vendors文件大小達(dá)到846kb壁榕,加載耗時達(dá)到7.38s左右,首屏白屏?xí)r間過長。
針對這個進(jìn)行以下優(yōu)化:
- 路由懶加載
這個我在項目里已經(jīng)做到了,但是針對這個匯總再簡單總結(jié)下
{
path: '/',
name: 'home',
component: () => import(/* webpackChunkName: "home" */ './views/home/index.vue'),
meta: { isShowHead: true }
}
我這里是結(jié)合ES 提出的 import
方法和webpack魔法注釋 /* webpackChunkName: "group-foo" */
輕松實現(xiàn)路由懶加載
- 開啟服務(wù)器Gzip
盡管第一步已經(jīng)做到了,但仍然有846k的大小,所以需要繼續(xù)優(yōu)化辜纲。開啟Gzip就是一種壓縮技術(shù),需要前端提供壓縮包拦耐,然后在服務(wù)器開啟壓縮耕腾,文件在服務(wù)器壓縮后傳給瀏覽器,瀏覽器解壓后進(jìn)行再進(jìn)行解析杀糯。
首先安裝webpack提供的compression-webpack-plugin
進(jìn)行壓縮,然后在vue.config.js:
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js', 'css']
......
plugins: [
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
})
]
....
然后在Nginx配置
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
此時我們再看chunk-vendors文件大小達(dá)到227k扫俺,耗時1.7s
- 啟動CDN加速
我們繼續(xù)采用cdn的方式來引入一些第三方資源,就可以緩解我們服務(wù)器的壓力固翰,原理是將我們的壓力分給其他服務(wù)器點狼纬。
首先在index.html中:
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.3/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.8.2/index.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.js"></script>
然后在vue.config.js中通過externals外部擴展,可以忽略不需要打包的庫:
module.exports = {
......
configureWebpack: (config) => ({
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'axios': 'axios',
'element-ui': 'ElementUI'
}
})
......
}
main.js
import Vue from 'vue' // 下面有用到所以沒注釋
// import ElementUI from 'element-ui' // 注釋
// import axios from 'axios' // 注釋
store.js
// import Vue from 'vue' // 注釋
// Vue.use(Vuex) // 注釋
import Vuex from 'vuex'
router.js
// import Vue from 'vue' // 注釋
// Vue.use(Router) // 注釋
import Router from 'vue-router'
這個時候我們再來看下效果:
可以看到chunk-verdors文件已減小到20.9kb骂际,耗時172ms疗琉,基本項目秒開無壓力了。
- 其他優(yōu)化點
——在vue.config.js中設(shè)置productionSourceMap:false這樣打包后map文件就沒了歉铝,map文件的作用在于:項目打包后盈简,代碼都是經(jīng)過壓縮加密的,如果運行時報錯犯戏,輸出的錯誤信息無法準(zhǔn)確得知是哪里的代碼報錯送火。有了map就可以像未加密的代碼一樣,準(zhǔn)確的輸出是哪一行哪一列有錯先匪。如果不需要的話可以這樣操作。
——修改uglifyOptions去除console來減少文件大小弃衍,如果代碼中打了很log呀非,這個優(yōu)化還是有點效果的。
代碼層面優(yōu)化
針對vue項目代碼層面優(yōu)化就得回歸到.vue文件中對HTML镜盯、CSS岸裙、javascript進(jìn)行優(yōu)化,那么主要就是<template>
速缆、<style>
降允、<script>
中可優(yōu)化的點:
- computed 和 watch 區(qū)分使用場景
- computed: 是計算屬性,依賴其它屬性值艺糜,并且 computed 的值有緩存剧董,只有它依賴的屬性值發(fā)生改變幢尚,下一次獲取 computed 的值時才會重新計算 computed 的值。當(dāng)我們需要進(jìn)行數(shù)值計算翅楼,并且依賴于其它數(shù)據(jù)時尉剩,應(yīng)該使用 computed,因為可以利用 computed 的緩存特性毅臊,避免每次獲取值時理茎,都要重新計算;
- watch:類似于某些數(shù)據(jù)的監(jiān)聽回調(diào) 管嬉,每當(dāng)監(jiān)聽的數(shù)據(jù)變化時都會執(zhí)行回調(diào)進(jìn)行后續(xù)操作皂林;當(dāng)我們需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時,應(yīng)該使用 watch蚯撩,使用 watch 選項允許我們執(zhí)行異步操作 ( 訪問一個 API )础倍,限制我們執(zhí)行該操作的頻率,并在我們得到最終結(jié)果前求厕,設(shè)置中間狀態(tài)著隆。這些都是計算屬性無法做到的。
- v-if 和 v-show 區(qū)分使用場景
v-if 適用于在運行時很少改變條件呀癣,不需要頻繁切換條件的場景美浦;v-show則適用于需要非常頻繁切換條件的場景。這里要說的優(yōu)化點在于減少頁面中 dom 總數(shù)项栏,我比較傾向于使用 v-if浦辨,因為減少了 dom 數(shù)量。 - v-for 遍歷必須為 item 添加 key沼沈,且避免同時使用 v-if
- v-for 遍歷必須為 item 添加 key流酬,循環(huán)調(diào)用子組件時添加 key,key 可以唯一標(biāo)識一個循環(huán)個體列另,可以使用例如 item.id 作為 key
- 避免同時使用 v-if芽腾,v-for 比 v-if 優(yōu)先級高,如果每一次都需要遍歷整個數(shù)組页衙,將會影響速度摊滔。
- 圖片懶加載
vue-lazyload可參考下官方介紹,不再贅述店乐。 - style方面
- style文件按照模塊劃分艰躺,無論放在內(nèi)外都
<style lang="scss" scoped>
鎖住樣式,目的就是避免多人開發(fā)樣式混亂眨八,鎖住之后內(nèi)部的命名也可以很簡短腺兴。 - 全局樣式抽象化,將公共組件以及elementUI修改的樣式建議都放到公共樣式廉侧,抽象做的越好說明你的樣式文件體積越小页响,復(fù)用率越高篓足。
- style文件按照模塊劃分艰躺,無論放在內(nèi)外都
- 合理組件化
- 使用重復(fù)率高的模塊盡量封裝成組件,包括布局的封裝拘泞,按鈕纷纫,表單,提示框陪腌,彈出框等辱魁,封裝的組件只處理
類似業(yè)務(wù),復(fù)用率越高越好 - 封裝組件配置的 props 細(xì)化到一個字段诗鸭,不要一個對象傳進(jìn)去染簇,這樣只傳需要修改的參數(shù),在子組件 props 里加數(shù)據(jù)類型强岸,是否必傳锻弓,以及默認(rèn)值,便于排查錯誤蝌箍,讓傳值更嚴(yán)謹(jǐn)青灼。
- 使用重復(fù)率高的模塊盡量封裝成組件,包括布局的封裝拘泞,按鈕纷纫,表單,提示框陪腌,彈出框等辱魁,封裝的組件只處理
結(jié)尾:另外還有諸如SSR(服務(wù)端渲染),首頁骨架屏加載等優(yōu)化方法都可以考慮下妓盲,還有其他優(yōu)化點鐵子們可以評論區(qū)一塊討論下~