總結(jié)4個(gè)方面優(yōu)化Vue項(xiàng)目
運(yùn)行時(shí)優(yōu)化
1、使用v-if代替v-show
兩者的區(qū)別是:v-if不渲染DOM,v-show會(huì)預(yù)渲染DOM
除以下情況使用v-show,其他情況盡量使用v-if
有預(yù)渲染需求
需要頻繁切換顯示狀態(tài)
2、v-for必須加上key,并避免同時(shí)使用v-if
一般我們?cè)趦煞N常見的情況下會(huì)傾向于這樣做:
為了過濾一個(gè)列表中的項(xiàng)目
比如 v-for="user in users" v-if="user.isActive"。在這種情形下,請(qǐng)將 users替換為一個(gè)計(jì)算屬性 (比如 activeUsers),讓其返回過濾后的列表
為了避免渲染本應(yīng)該被隱藏的列表
比如 v-for="user in users" v-if="shouldShowUsers"。這種情形下,請(qǐng)將 v-if 移動(dòng)至容器元素上 (比如 ul, ol)
3、事件及時(shí)銷毀
Vue組件銷毀時(shí),會(huì)自動(dòng)清理它與其它實(shí)例的連接,解綁它的全部指令及事件監(jiān)聽器,但是僅限于組件本身的事件。
也就是說,在js內(nèi)使用addEventListener等方式是不會(huì)自動(dòng)銷毀的,我們需要在組件銷毀時(shí)手動(dòng)移除這些事件的監(jiān)聽,以免造成內(nèi)存泄露,如:
created() { addEventListener('touchmove', this.touchmove, false) }, beforeDestroy() { removeEventListener('touchmove', this.touchmove, false) }
首屏優(yōu)化
1、圖片裁剪、使用webp
- 圖片需要裁剪,一般使用二倍圖即可
- 盡量使用webp圖片
- 如果使用了vue-lazyload插件,可以使用以下方法一鍵替換webp(替換使用v-lazy指令的圖片)
Vue.use(VueLazyload, { error: require('./assets/img/defaultpic_small.png'), filter: { webp (listener: any, options: any) { if (!options.supportWebp) return // listener.src += '.webp' } } });
2、資源提前請(qǐng)求
經(jīng)測(cè)試,Vue項(xiàng)目中各文件的加載順序?yàn)椋簉outer.js、main.js、App.vue、[-page-].vue、[component].vue,如圖:
其中,router的加載時(shí)間相比于page.vue快近100ms,如果page.vue的文件較多,時(shí)間差異會(huì)更大
所以,可以在頁面掛載、渲染的同時(shí)去請(qǐng)求接口數(shù)據(jù),如在router.js中請(qǐng)求數(shù)據(jù):
import Router from 'vue-router' import store from './store' store.dispatch('initAjax')
3、異步路由
使用異步路由可以根據(jù)URL自動(dòng)加載所需頁面的資源,并且不會(huì)造成頁面阻塞,較適用于移動(dòng)端頁面
建議主頁面直接import,非主頁面使用異步路由
使用方式:
{ path: '/order', component: () => import('./views/order.vue') }
4、異步組件
不需要首屏加載的組件都使用異步組件的方式來加載(如多tab),包括需要觸發(fā)條件的動(dòng)作也使用異步組件(如彈窗)
使用方式為:v-if來控制顯示時(shí)機(jī),引入組件的Promise即可
<template> <div> <HellowWorld v-if="showHello" /> </div> </template> <script> export default { components: { HellowWorld: () => import('../components/HelloWorld.vue') }, data() { return { showHello: false } }, methods: { initAsync() { addEventListener('scroll', (e) => { if (scrollY > 100) { this.showHello = true } }) } } } </script>
5、使用輕量級(jí)插件、異步插件
使用webpack-bundle-analyzer查看項(xiàng)目所有包的體積大小,較大的插件包盡量尋找輕量級(jí)的替代方案
首屏用不到的插件、或只在特定場(chǎng)景才會(huì)用到的插件使用異步加載(如定位插件,部分情況可以通過URL傳遞經(jīng)緯度;或生成畫報(bào)插件,需要在點(diǎn)擊時(shí)觸發(fā));插件第一次加載后緩存在本地,使用方式為:
// 以定位插件為例 const latitude = getUrlParam('latitude') const longitude = getUrlParam('longitude') // 如果沒有經(jīng)緯度參數(shù),則使用定位插件來獲取經(jīng)緯度 if (!latitude || !longitude) { // 首次加載定位插件 // webpack4寫法,若使用webpack3及以下,則await import('locationPlugin')即可 if (!this.WhereAmI) this.WhereAmI = (await import('locationPlugin')).default // do sth... }
6、公用CDN
使用公用的CDN資源,可以起到緩存作用,并減少打包體積
網(wǎng)絡(luò)優(yōu)化
1、減少網(wǎng)絡(luò)請(qǐng)求
瀏覽器對(duì)同一時(shí)間針對(duì)同一域名下的請(qǐng)求有一定數(shù)量限制(一般是6個(gè)),超過限制數(shù)目的請(qǐng)求會(huì)被阻塞
首屏盡可能減少同域名的請(qǐng)求,包括接口和js;按需減少首屏的chunk.js,合并接口請(qǐng)求
2、合理使用preload、dns-prefetch、prefetch
- preload具有較高的加載優(yōu)先級(jí),它可以利用間隙時(shí)間預(yù)加載資源,將加載和執(zhí)行分離開,不阻塞渲染和document的onload事件
- 每次與域名連接都需要進(jìn)行DNS解析,使用dns-prefetch可以預(yù)解析域名的DNS
- prefetch會(huì)預(yù)加載頁面將來可能用到的一些資源,優(yōu)先級(jí)較低;對(duì)首屏渲染要求較高的項(xiàng)目不建議使用
三者的使用方式,在head標(biāo)簽中添加(vue-cli-3已經(jīng)做了相應(yīng)配置):
<head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <link rel="icon" href="/dist/favicon.ico" rel="external nofollow" /> <!-- dns-prefetch寫法 --> <link rel="dns-prefetch" rel="external nofollow" /> <title>md-config</title> <!-- preload寫法,as屬性必須 --> <link href="/dist/css/app.52dd885e.css" rel="external nofollow" rel="preload" as="style" /> <link href="/dist/js/app.05faf3b5.js" rel="external nofollow" rel="preload" as="script" /> <link href="/dist/js/chunk-vendors.04343b1f.js" rel="external nofollow" rel="external nofollow" rel="preload" as="script" /> <!-- prefetch寫法 --> <link href="/dist/js/chunk-vendors.04343b1f.js" rel="external nofollow" rel="external nofollow" rel="prefetch" /> </head>
3、PWA
PWA支持緩存HTML文檔、接口(get)等,降低頁面白屏?xí)r間
這樣即使在弱網(wǎng)甚至斷網(wǎng)情況下,也能迅速展示出頁面
編譯打包優(yōu)化
1、升級(jí)Vue-Cli-3
vue-cli-3采用webpack4+babel7,對(duì)編譯打包方面做了很多優(yōu)化(成倍的提升),使用yarn作為包管理工具,并且對(duì)很多優(yōu)化的最佳實(shí)踐做了默認(rèn)配置
經(jīng)測(cè)試,將項(xiàng)目從vue-cli-2遷移到vue-cli-3之后,速度變化為:
編譯時(shí)間:44s --> 7s
打包時(shí)間:55s --> 11s
效率提升非常明顯
2、SSR
對(duì)加載性能要求較高的項(xiàng)目建議升級(jí)SSR
相關(guān)文章
Vue點(diǎn)擊在彈窗外部實(shí)現(xiàn)一鍵關(guān)閉的示例代碼
在Vue應(yīng)用中,彈窗是一個(gè)常見的交互元素,有時(shí)我們可能希望用戶點(diǎn)擊彈窗外部時(shí),彈窗能夠自動(dòng)關(guān)閉,本文主要介紹了Vue點(diǎn)擊在彈窗外部實(shí)現(xiàn)一鍵關(guān)閉的示例代碼,感興趣的可以了解一下2024-06-06vue3?elementPlus?table實(shí)現(xiàn)列寬可拖拽功能
這篇文章主要介紹了vue3?elementPlus?table實(shí)現(xiàn)列寬可拖拽功能,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08Vue+jsPlumb實(shí)現(xiàn)連線效果(支持滑動(dòng)連線和點(diǎn)擊連線)
jsPlumb 是一個(gè)比較強(qiáng)大的繪圖組件,它提供了一種方法,主要用于連接網(wǎng)頁上的元素。本文將利用jsPlumb實(shí)現(xiàn)連線效果,同時(shí)支持滑動(dòng)連線和點(diǎn)擊連線,感興趣的可以了解一下2023-01-01Vue.js使用computed屬性實(shí)現(xiàn)數(shù)據(jù)自動(dòng)更新
在Vue組件中,computed屬性是在組件的選項(xiàng)對(duì)象中聲明的,你可以把它們想象成組件的一個(gè)小功能,告訴Vue當(dāng)某些數(shù)據(jù)變化時(shí),如何更新界面,本文給大家介紹了Vue.js使用computed屬性實(shí)現(xiàn)數(shù)據(jù)自動(dòng)更新,需要的朋友可以參考下2024-06-06uniapp開發(fā)打包多端應(yīng)用完整方法指南
這篇文章主要介紹了uniapp開發(fā)打包多端應(yīng)用完整流程指南,包括了uniapp打包小程序,uniapp打包安卓apk,uniapp打包IOS應(yīng)用,需要的朋友可以參考下2022-12-12詳解無限滾動(dòng)插件vue-infinite-scroll源碼解析
這篇文章主要介紹了詳解無限滾動(dòng)插件vue-infinite-scroll源碼解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05vue項(xiàng)目配置同一局域網(wǎng)可使用ip訪問的操作
這篇文章主要介紹了vue項(xiàng)目配置同一局域網(wǎng)可使用ip訪問的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10Vue使用mixins實(shí)現(xiàn)壓縮圖片代碼
本篇文章主要介紹了Vue使用mixins實(shí)現(xiàn)壓縮圖片代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03Vue.js@2.6.10更新內(nèi)置錯(cuò)誤處機(jī)制Fundebug同步支持相應(yīng)錯(cuò)誤監(jiān)控
這篇文章主要介紹了Vue.js@2.6.10更新內(nèi)置錯(cuò)誤處機(jī)制,F(xiàn)undebug同步支持相應(yīng)錯(cuò)誤監(jiān)控 ,需要的朋友可以參考下2019-05-05