使用v-memo緩存模板子樹提高應(yīng)用性能詳解
引言
Vue3 為我們提供了幾項(xiàng)開箱即用的重大性能改進(jìn),但也引入了一些額外的手動功能,可以幫助提高我們的應(yīng)用性能。
在這節(jié)課中,我們介紹一下,在 Vue 3.2 中引入新指令 v-memo
。引入這個指令的目的是幫助我們提高中型/大型 Vue 應(yīng)用程序的性能,小項(xiàng)目大家根據(jù)需要自行決定。
v-memo 是做什么的?
官網(wǎng)對 v-memo
定義是這樣的:
緩存一個模板的子樹。在元素和組件上都可以使用。為了實(shí)現(xiàn)緩存,該指令需要傳入一個固定長度的依賴值數(shù)組進(jìn)行比較。如果數(shù)組里的每個值都與最后一次的渲染相同,那么整個子樹的更新將被跳過。舉例來說:
看起來有點(diǎn)繞,但實(shí)際上,很好理解。v-memo
所做的與我們現(xiàn)有的計(jì)算屬性一樣,只不過 v-memo
的對象是 DOM。
這個新指令將緩存它所控制的DOM部分,如果一個特定的值發(fā)生變化,只需運(yùn)行更新并重新渲染。這些值是由我們自己手動設(shè)置。
事例
<template> <div> ..the rest of the component <div v-memo="[myValue]"> <svg > <title>{{MyValue}}</title> ... </svg> <vue-custom-element :value="myValue"></vue-custom-element> </div> </div> </template>
對上面解釋一下: v-memo
通常是作為組件的一部分來使用的,它只是影響組件 dom 的一個子集。
<div v-memo="[myValue]">
接著,我們將 v-memo
分配給了一個特定的 DIV
和它的所有子元素。當(dāng)調(diào)用 v-memo
時,需要傳遞一個值數(shù)組,以控制子樹的渲染。
數(shù)組接受一個或多個值 v-memo="[valueOne, valueTwo]"
,也接受像 v-memo="myValue === true"
這樣的表達(dá)。
另外:用一個空數(shù)組調(diào)用 v-memo
相當(dāng)于使用v-once
,只會渲染該部分組件一次。
<svg > <title>{{MyValue}}</title> ... </svg> <vue-custom-element :value="myValue"></vue-custom-element>
同在看下子樹的內(nèi)容。在我們的例子中,使用了一個 svg 元素和一個自定義 Vue 組件 vue-custom-element
。這樣做是為了說明一件事:v-memo
包含任何元素。
錯誤的使用方式
<div v-memo="[myValue]"> <p>Static content, no vue values here</p> </div>
在上面的例子中,包含在 v-memo
中的子樹不需要被緩存,因?yàn)樗庆o態(tài)的,不會改變(它不包括任何Vue變量)。Vue3 會對靜態(tài)進(jìn)行一個提升,以便提高性能。
在一個靜態(tài)的HTML上添加 v-memo
是沒啥作用,不管這個HTML有多復(fù)雜。
管理更新
在有些情況下,v-memo
不僅可以用來提高性能,還可以通過控制組件的更新周期,實(shí)際改善UX(用戶體驗(yàn))。
<div v-memo="[allFieldChanged]"> <p>{{ field1 }}</p> <p>{{ field2 }}</p> <p>{{ field3 }}</p> <p>{{ field4 }}</p> </div>
在上面的例子中,改變一個單獨(dú)的字段,例如 field1
,并不會導(dǎo)致重新渲染。新的字段將在所有字段都被更新后顯示。
最近遇到一個情況,一個子組件會對一個大的JSON數(shù)據(jù)集進(jìn)行更新和響應(yīng)。在這種情況下,使用 v-memo
真的很有幫助,當(dāng)所有的變化都完成后,就可以觸發(fā)更新。
與 v-for 結(jié)合使用
使用 v-memo
的一個最常見的用例是在處理使用 v-for
渲染的非常大的列表時。
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]"> <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p> <p>...more child nodes</p> </div>
如果不在上面的代碼中使用 v-memo
,selected
變量的每一次改變都會導(dǎo)致列表的完全重新渲染。新指令提供的緩存,允許只更新表達(dá)式 item.id === selected
發(fā)生變化的行,也就是當(dāng)某個項(xiàng)被選中或者取消時。
如果我們考慮一個有 1000 條數(shù)據(jù)的列表。使用上述代碼的 v-memo
,可以為每一個變化節(jié)省998個條重新渲染。
無意中停止了子組件觸發(fā)的更新
我們知道 v-memo
會停止子樹渲染更新,但需要注意的是,使用這個指令實(shí)際上會停止任何可能被更新觸發(fā)的代碼的執(zhí)行,如 watch 函數(shù)等。
<div v-memo="[points > 1000]"> <myComponent :points="points" /> </div> //myComponent <isLevel1 v-if="points <= 1000">....</isLevel1> <isLevel2 v-if="points > 1000">...</isLevel2> <script> ..., watch: { points() { logPointChange(); } }
在上面的代碼中,如果我們的 points
值是 1000 以內(nèi)變化,那么 watch
函數(shù)不會被執(zhí)行,直到 points
的值大于 1000 才會觸發(fā) watch 函數(shù)的執(zhí)行。
總結(jié)
這個新的指令對于要求性能極高的項(xiàng)目有很在幫助了,一般是在比較大型的項(xiàng)目中使用的,當(dāng)然小型項(xiàng)目,大家可以根據(jù)項(xiàng)目需要進(jìn)行食用。
代碼部署后可能存在的BUG沒法實(shí)時知道,事后為了解決這些BUG,花了大量的時間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。
更多關(guān)于v-memo緩存模板子樹的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于vue.js實(shí)現(xiàn)側(cè)邊菜單欄
這篇文章主要為大家詳細(xì)介紹了基于vue.js實(shí)現(xiàn)側(cè)邊菜單欄的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03使用vue-video-player實(shí)現(xiàn)直播的方式
在開發(fā)期間使用過video.js、mui-player等插件,發(fā)現(xiàn)這些video插件對移動端的兼容性都不友好,最后發(fā)現(xiàn)一個在移動端兼容不錯的插件vue-video-player,下面通過場景分析給大家介紹使用vue-video-player實(shí)現(xiàn)直播的方法,感興趣的朋友一起看看吧2022-01-01el-select 點(diǎn)擊按鈕滾動到選擇框頂部的實(shí)現(xiàn)代碼
本文通過實(shí)例代碼給大家分享el-select 點(diǎn)擊按鈕滾動到選擇框頂部效果,主要代碼是在visibleChange在這個popper里面找到.el-select-dropdown__list,感興趣的朋友跟隨小編一起看看吧2024-05-05使用vue點(diǎn)擊li,獲取當(dāng)前點(diǎn)擊li父輩元素的屬性值方法
今天小編就為大家分享一篇使用vue點(diǎn)擊li,獲取當(dāng)前點(diǎn)擊li父輩元素的屬性值方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue項(xiàng)目實(shí)現(xiàn)添加圖片裁剪組件
這篇文章主要為大家詳細(xì)介紹了vue項(xiàng)目實(shí)現(xiàn)添加圖片裁剪組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Vant中List組件immediate-check=false無效的解決
這篇文章主要介紹了Vant中List組件immediate-check=false無效的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01