静态提升
vue2中当我们写如下代码
<h1>hello</h1>
静态节点如下
render(){
createVNode("h1",null,"Hello World")
}
Vue3中认为静态节点就不会改变了,没有必要放在渲染函数中,因为渲染函数在更改时会反复运行。如下只创建一次,之后在render函数中重复使用就可以了
const hoisted = createVNode("h1",null,"Hello World")
function render(){
// 直接使用hoisted就行
}
静态属性提升
<div class = "user">
{{user,name}}
</div>
静态属性提出来了,不用重复调用
const hoisted = {class:"user"}
function render(){
createVNode("div",hoisted,user.name)
}
预字符串化
如下组件代码,我们可以发现静态代码很多,动态代码只有user.name
<div class="menu-bar">
<div class="logo">
<h1>logo</h1>
</div>
<ul class="nav">
<li>menu</li>
<li>menu</li>
<li>menu</li>
<li>menu</li>
</ul>
<div class="user">
{{user.name}}
</div>
</div>
Vue3会发现遇到了大量的连续的静态元素,编译器就会把静态元素编译成字符串大概如下
const _hoisted_2 = _createStaticVNode("<div class=\"logo\"><h1>logo</h1></div>......")
而Vue2会编译成大量的虚拟节点树,重新对比渲染的时候会全部对比,而Vue3只会对比动态的。
缓存事件处理函数
<a-button @click="count++"></a-button>
Vue2
render(ctx){
return createVNode("button",{
onClick:function($event){
ctx.count++
}
})
}
Vue3
//_cache缓存对象,如果有缓存直接缓存,保证事件处理函数只生成一次
render(ctx,_cache){
return createVNode("button",{
onClick:cache[0] || (cache[0] = ($event) => (ctx.count++))
}
})
}
Block Tree
Vue2在对比新旧树的时候,并不知道哪些节点是静态的,哪些是动态的,只能一层一层比较,浪费了大量时间在对比静态节点上.Vue3利用编译器,把动态节点做标记只对比动态节点
PatchFlag
Vue2在对比每一个节点时,并不知道这个节点的哪些相关信息会发生变化,因此只能依次对比,对比属性有没有变化,内容有没有变化等等
Vue3中会记录一个动态节点哪里发生了变化,如果只有内容变化就只对比内容