Vue的Compile阶段是将模板解析成AST并分析依赖收集,生成渲染函数的阶段。在这个阶段,Vue会对静态节点进行标记,优化渲染性能。其中,有一个关键的标记项就是 optimize。
optimize
的主要作用是标记已知的静态根节点。如果一个静态节点不是根节点,那么其子节点将可能会发生变化,需要被重新渲染。但是,如果该节点被标记为静态节点,则可以避免对其进行不必要的渲染。而且因为它的子节点是静态的,所以它们也会被标记为静态节点。
下面是一个例子,演示如何使用 optimize 标记静态节点。
<template>
<div>
<div class="static-text">This is a static text.</div>
<p>{{dynamicText}}</p>
</div>
</template>
在编译过程中,Vue会将其转化为AST节点,代码如下:
{
tag: 'div',
children: [
{
tag: 'div',
attrsList: [
{name: 'class', value: 'static-text'}
],
static: true, // 静态节点标记
parent: [Circular],
type: 1,
children: [
{
text: 'This is a static text.',
type: 3
}
]
},
{
tag: 'p',
parent: [Circular],
type: 1,
children: [
{
expression: '_s(dynamicText)', // 动态文本节点不是静态节点,不做标记
text: '{{dynamicText}}',
type: 2
}
]
}
]
}
在AST节点中,静态节点的 type
属性会被标记为 1
,同时还会设置 static
属性为 true
。这样,在执行 render 函数时,Vue就知道哪些节点可以被优化为静态节点。
下面再看一个 more 示例,更加直观地演示了 optimize 如何标记静态节点。
<template>
<div>
<div class="static-text" v-if="isShow">This is a static text.</div>
<p>{{dynamicText}}</p>
</div>
</template>
在编译过程中,会产生如下 AST 节点:
{
tag: 'div',
children: [
{
type: 12,
expression: '_c("div",{staticClass:"static-text"},[_v("This is a static text.")],1)', // 运行时渲染函数表达式
static: false, // 非静态
ifConditions: [
{
exp: 'isShow',
block: [Circular]
}
]
},
{
tag: 'p',
parent: [Circular],
type: 1,
children: [
{
expression: '_s(dynamicText)',
text: '{{dynamicText}}',
type: 2
}
]
}
]
}
在这个例子中,由于 v-if 指令的存在,static
属性被标记为 false
。因为 v-if 指令会根据条件动态地插入/移除节点,所以由 v-if 生成的节点不可能是静态节点。这时,Vue 会优先考虑标记那些不被 v-if 控制的静态节点。这也是 optimize 标记静态节点的难点所在。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue原理Compile之optimize标记静态节点源码示例 - Python技术站