什么是 HoistStatic 和 CacheHandler
都是优化手段
什么是 HoistStatic
- 将静态节点的定义,提升到父作用域,缓存起来
- 多个相邻的静态节点,会被合并起来
- 典型的拿空间换时间的优化策略
还是来看下 https://vue-next-template-explorer.netlify.app/ 这个
html
<div>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<!-- <span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span>
<span>hello vue3</span> -->
<span>{{msg}}</span>
</div>
生成 AST 树
js
import {
createElementVNode as _createElementVNode,
toDisplayString as _toDisplayString,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from 'vue';
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
_openBlock(),
_createElementBlock('div', null, [
_createElementVNode('span', null, 'hello vue3'),
_createElementVNode('span', null, 'hello vue3'),
_createElementVNode('span', null, 'hello vue3'),
_createElementVNode(
'span',
null,
_toDisplayString(_ctx.msg),
1 /* TEXT */,
),
])
);
}
// Check the console for the AST
然后在 Options
里勾选 hoistStatic
, AST 树变化
将静态节点的定义,提升到父作用域,缓存起来
js
import {
createElementVNode as _createElementVNode,
toDisplayString as _toDisplayString,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from 'vue';
const _hoisted_1 = /*#__PURE__*/ _createElementVNode(
'span',
null,
'hello vue3',
-1 /* HOISTED */,
);
const _hoisted_2 = /*#__PURE__*/ _createElementVNode(
'span',
null,
'hello vue3',
-1 /* HOISTED */,
);
const _hoisted_3 = /*#__PURE__*/ _createElementVNode(
'span',
null,
'hello vue3',
-1 /* HOISTED */,
);
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
_openBlock(),
_createElementBlock('div', null, [
_hoisted_1,
_hoisted_2,
_hoisted_3,
_createElementVNode(
'span',
null,
_toDisplayString(_ctx.msg),
1 /* TEXT */,
),
])
);
}
// Check the console for the AST
多个相邻的静态节点,会被合并起来
js
import {
createElementVNode as _createElementVNode,
toDisplayString as _toDisplayString,
createStaticVNode as _createStaticVNode,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from 'vue';
const _hoisted_1 = /*#__PURE__*/ _createStaticVNode(
'<span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span><span>hello vue3</span>',
12,
);
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
_openBlock(),
_createElementBlock('div', null, [
_hoisted_1,
_createElementVNode(
'span',
null,
_toDisplayString(_ctx.msg),
1 /* TEXT */,
),
])
);
}
// Check the console for the AST
什么是 CacheHandler
继续 https://vue-next-template-explorer.netlify.app/ 这个
html
<div>
<span @click="clickHandler">hello vue3</span>
</div>
生成 AST 树
js
import {
createElementVNode as _createElementVNode,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from 'vue';
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
_openBlock(),
_createElementBlock('div', null, [
_createElementVNode(
'span',
{ onClick: _ctx.clickHandler },
'hello vue3',
8 /* PROPS */,
['onClick'],
),
])
);
}
// Check the console for the AST
然后在 Options
里勾选 cacheHandlers
, AST 树变化
通过
_cache[0]
缓存函数
js
import {
createElementVNode as _createElementVNode,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from 'vue';
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (
_openBlock(),
_createElementBlock('div', null, [
_createElementVNode(
'span',
{
onClick:
_cache[0] ||
(_cache[0] = (...args) =>
_ctx.clickHandler && _ctx.clickHandler(...args)),
},
'hello vue3',
),
])
);
}
// Check the console for the AST