携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第34天,点击查看活动详情
这一次就到了第九章,diff算法,这一章感觉应该比较难,之前看过知乎上鱿鱼须回答虚拟DOM性能是不是比真实DOM性能好。其根本原因就是虚拟DOM可以通过diff算法实现最细粒度的更新,在这一块上vue3相比vue2提升也很大,因此才保证了vue3性能上的优势。
在之前那一章中,我没有写diff算法那块,因为我觉得我对diff算法也没什么了解,而且书中的讲的方法也太简单。在上一章中,作者没有diff,直接卸载掉全部旧节点,再加载新节点,我想哪怕浏览器也不会采用这么粗暴的方法。
比如我们现在有这样的节点,可以发现,只有p内的文本变了,其他所有结构都没变
const oldNode = {
type:'div',
children:[
{type:'p',children:1},
{type:'p',children:2}
]
}
const newNode = {
type:'div',
children:[
{type:'p',children:3},
{type:'p',children:4}
]
}
按照之前的办法,卸载全部旧节点,再加载新节点,那我们最起码要操作4次DOM,如果我们仅是修改p的内容,那么我们只需要修改2次DOM 属性而已,这可以算是几倍的性能差了。如果网页的结构更加复杂,dom数量更多,那么我们可以提高几百倍的性能吧。
但是diff算法并非这么简单,上述这个例子很有局限性,它的子节点数量是没有变化的,但大部分情况,我们子节点的数量会变化,比如常用的v-if。
这时候我们应该怎么处理才算合理呢?答案是总是优先遍历子节点数量少的Node,无论是新Node还是旧Node,子节点数量少就意味着变化比较大,我们应该更多的调用patch,这样才能把所有的不同找出来,正确的渲染元素,正确的渲染节点的变化。