不必爭(zhēng)論 v-if 和 v-show,Vue3 新指令來了
v-if, v-show 控制的是是否渲染,而真正的性能瓶頸,往往在于是否需要重新渲染。
面對(duì)這個(gè)問題,v-if 和 v-show 顯得有些無力,而 Vue3 有一個(gè)專為解決此問題的指令——v-memo。

什么是 v-memo?
v-memo 是一個(gè)指令,作用是有條件地跳過一個(gè)元素或組件的更新,語法如下:
<div v-memo="[depA, depB]">
...
</div>v-memo 接收一個(gè)依賴數(shù)組,只有當(dāng)數(shù)組中至少一個(gè)值與上次渲染相比發(fā)生了變化,Vue 才會(huì)重新渲染這個(gè) div 及其子節(jié)點(diǎn)。否則,將跳過 diff 過程。
v-memo 的使用場(chǎng)景
v-memo 不是用來替代 v-if 或 v-show 的,它是專門解決那些令人棘手的渲染性能問題。
其最經(jīng)典、最有效的應(yīng)用場(chǎng)景就是優(yōu)化超長(zhǎng) v-for 列表,假設(shè)有一個(gè)包含 1000 個(gè)用戶的列表,每個(gè)用戶都有 name 和 status(在線/離線)兩個(gè)屬性:
沒有 v-memo 的版本:

問題在于,如果其中一個(gè)用戶的 status 發(fā)生改變,Vue 理論上需要遍歷整個(gè)列表,為每個(gè)節(jié)點(diǎn)創(chuàng)建新的 VNode 并 diff。
使用 v-memo 的版本:
<template>
<div v-for="user in users" :key="user.id" v-memo="[user.status]">
<p>{{ user.name }}</p>
<p :class="user.status === 'online' ? 'green' : 'grey'">
{{ user.status }}
</p>
</div>
</template>需要注意的是 v-memo="[user.status]"。
當(dāng)某個(gè)用戶的 status 改變時(shí),只有他對(duì)應(yīng)的 div 的 v-memo 依賴項(xiàng)發(fā)生了變化,于是只有這個(gè) div 會(huì)被重新渲染。Vue 會(huì)直接跳過其他 999 個(gè)用戶的整個(gè)更新過程。
通過一行代碼,我們將 O(n) 的更新檢查開銷,降低到了 O(1)(只更新變化的那一項(xiàng))。
對(duì)比 v-once
v-once 本質(zhì)上就是 v-memo 的一個(gè)特例,v-once 等同于 v-memo="[]"。因?yàn)橐蕾嚁?shù)組是空的,它永遠(yuǎn)不會(huì)改變,所以組件只會(huì)在首次渲染后被永久“凍結(jié)”。
v-if 和 v-show 的爭(zhēng)論,解決的是“有或無”的渲染問題,但現(xiàn)代前端應(yīng)用中,更大的性能挑戰(zhàn)來自于“多與少”的更新問題。

































