-
Diff算法優化:
- Vue2.0 中的虛拟Dom是全量的對比
-
Vue3.0 中新增了靜态标記(PatchFlag)
在與上次的虛拟節點進行對比的時候,隻對比帶有patch flag的節點
并且可以通過flag的資訊知道對比的内容
-
靜态标記
Vue3 中僅對靜态标記标記對象進行比較。<div> <p>wzl</p> <p>wzl</p> <p>wzl</p> <p>{{msg}}</p> </div>
可以看到,源碼中,對 msg 設計了靜态标記,這裡是1,後面跟注釋 TEXT ,代表這個标簽的 TEXT 資料是會動态變化的。import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue" export function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createBlock("div", null, [ _createVNode("p", null, "wzl"), _createVNode("p", null, "wzl"), _createVNode("p", null, "wzl"), _createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */) ])) }
-
hoistStatic靜态提升
- Vue2中無論元素是否參與更新,每次都會重新建立然後渲染
- Vue3中對不參與的更新元素會做靜态提升,隻會被建立一次,在渲染時直接引用
/*
靜态提升之前
*/
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("p", null, "111"),
_createVNode("p", null, "222"),
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
_createVNode("p", null, "333")
]))
}
/*
靜态提升之後
不參與的更新元素會做靜态提升,隻會被建立一次,在渲染時直接引用
*/
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "111", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "222", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "333", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_hoisted_2,
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),
_hoisted_3
]))
-
cacheHandelers事件偵聽器緩存
預設情況下onClick會被視為動态綁定,是以每次都會追蹤它的變化
但是是同一個函數,是以沒有變化,直接緩存起來複用即可
/*
開啟事件偵聽器緩存之前
*/
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", { onClick: _ctx.onClick }, null, 8 /* PROPS */, ["onClick"])
]))
}
/*
開啟事件偵聽器緩存之後
*/
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", {
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))
})
]))
}
_createVnode 的第二個屬性,從
{ onClick: _ctx.onClick }
變為了
{ onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args))) }
它的意思很明顯,onClick 方法被存入 cache。在使用的時候,如果能在緩存中找到這個方法,那麼它将直接被使用。如果找不到,那麼将這個方法注入緩存。總之,就是把方法給緩存了。
例如:
<div>
<button @click="onClick" @mouseover="onMouseover">btn</button>
<button @click="onClick1">btn</button>
</div>
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", {
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args))),
onMouseover: _cache[2] || (_cache[2] = (...args) => (_ctx.onMouseover(...args)))
}, "btn", 32 /* HYDRATE_EVENTS */),
_createVNode("button", {
onClick: _cache[3] || (_cache[3] = (...args) => (_ctx.onClick1(...args)))
}, "btn")
]))
}