在尤雨溪 - 聊聊 Vue.js 3.0 Beta 官方直播完整版 2020-04-21裏我發現了一個有意思的工具,輸入模板展示它編譯優化的結果,網址在這裏:https://vue-next-template-explorer.netlify.app/
留意圖片中,注意動態的 /* Text */
的註釋。識別 _openblock 後,vue 直接會找到帶動態屬性的節點(是AST裏面會有標識聲明),並且它標明瞭 /* Text */
所以 diff 時會直接比對它的文本屬性,節省了很大一筆 diff 遍歷的次數。
<div>
<span>hello</span>
<span>hello</span>
<span :id="test" :class="clazz">{{msg}}</span>
<span>hello</span>
<span>hello</span>
<span>hello</span>
<span>hello</span>
</div>
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("span", null, "hello"),
_createVNode("span", null, "hello"),
_createVNode("span", {
id: _ctx.test,
class: _ctx.clazz
}, _toDisplayString(_ctx.msg), 11 /* TEXT, CLASS, PROPS */, ["id"]),
_createVNode("span", null, "hello"),
_createVNode("span", null, "hello"),
_createVNode("span", null, "hello"),
_createVNode("span", null, "hello")
]))
}
// Check the console for the AST
能識別出第三個 span 是動態的,並且還會標識它的哪些屬性是動態的,其中 {{msg}} 是 TEXT,:class 是 CLASS,:id 是 PROPS
JSX 比起模板它的表達更加靈活,但因爲它過於靈活,就無法做到下面的優化:
import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
const _hoisted_1 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_2 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_3 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_4 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_5 = _createVNode("span", null, "hello", -1 /* HOISTED */)
const _hoisted_6 = _createVNode("span", null, "hello", -1 /* HOISTED */)
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_hoisted_2,
_createVNode("span", {
id: _ctx.test,
class: _ctx.clazz
}, _toDisplayString(_ctx.msg), 11 /* TEXT, CLASS, PROPS */, ["id"]),
_hoisted_3,
_hoisted_4,
_hoisted_5,
_hoisted_6
]))
}
// Check the console for the AST
直接把靜態節點抽離出去了,他只會編譯階段創建一遍,之後直接複用對象,不需要再創建了。還有一些其他的優化,比如說可以 cache 綁定的 click 函數,SSR 渲染直接變字符串輸出。