0
点赞
收藏
分享

微信扫一扫

Vue3是如何升级虚拟DOM模块的?

慎壹 2022-04-26 阅读 64
vue3vue.js

Vue3是如何升级虚拟DOM模块的?

静态标记(PatchFlag)

在Vue2中,元素的更新比较是采用的全量对比的方式,虽然借鉴了react的diff算法中同级对比的方式进行了优化,但依然会对比部分静态节点,这明显还有优化空间。

所以在Vue3中采用了静态标记(PatchFlag)的方式对这部分进行优化。在render函数中就将每个节点进行分析,为动态节点进行标记,标明该节点是未来有可能变化的节点(即动态节点);并且PatchFlag枚举定义了十几种类型,更精确的定位需要对比节点的类型。

现有如下DOM结构:

<div class="message">
    <div class="time">
        <p>时间:</p>
        <p>{{time}}</p>
    </div>
    <div class="position">
        <p>地点:</p>
        <p>{{position}}</p>
    </div>
    <div class="name">
        <p>人物:</p>
        <p>{{name}}</p>
    </div>
</div>

对应的DOM树为:

蓝色的为静态节点,红色的为动态节点。

假设现在触发了一次数据变化,上述DOM结构中三个变量(time、position、name)均发生了变化。

Vue2的Diff算法采用全量对比的方式:顶层对比一次,第二层对比三次,底层对比六次,共对比10次,结果是找到了3个需要更新的节点。

而Vue3在创建render函数时就将上图中3个未来可能会发生变化的节点进行了对应的静态标记,所以在视图更新时Diff算法仅对比底层的3个红色节点,就找到了全部的3个需要更新的节点。

静态提升(hoistStatic)

Vue3在创建render函数时,会将函数内的静态变量提到render函数外,这也意味着这些静态变量不再参与响应式逻辑(因为它们是常量,永远不会变化,所以能用const时就要用const)。

事件监听缓存(cacheHandler)

事件监听缓存是针对于有事件绑定的节点在Diff算法上的优化,因为在正常开发中,节点上的@click等事件是不会随着数据变化而变化的,所以在Vue3中哪怕静态节点上绑定了@click等事件,DOM更新时Diff算法也不会去比较该静态节点。

比如如下节点:

<div @click="submit">提交</div>

该节点在vue2中每次都会参与Diff比较,因为它有@click绑定,但事实上任何数据变了也不会影响submit函数,所以最好的情况就是将该节点看做一个静态节点,然而,vue3就是这样做的!Vue3会将该节点看做一个静态节点,永远不会参与Diff算法的比较。

举报

相关推荐

0 条评论