「React」浅析两大框架「DOM diff」

190 阅读2分钟

本篇博客用来记录我的学习成果
防止遗忘

是什么

「两个 DOM 得到 patch」

对比两棵虚拟 DOM 树的算法,当组件变化时,会 render 出一个新的虚拟 DOM,diff 算法对比新旧两棵 虚拟DOM 树之后,得到一个 patch,然后 React 用 patch 来更新真实的 DOM

patch(补丁):所有需要更新的东西的一个集合 ( 数组/对象,哪个节点变了,哪个属性变了等等... )

怎么做

官方文档解释

  1. 首先对比两颗树的根节点

    a. 如果根节点的类型改变了,比如 div 变成了span,那么直接认为整个树都变了,那就不往下对比节点了,直接删除对应的真实 DOM 树,创建新的真实 DOM 树

    b. 如果根节点的类型没有改变,就看属性变了没

    c. 如果没变,就保留对应的真实节点

    d. 如果变了,就只更新该节点的属性,补充性创建新节点(更更新 style 也一样)

  2. 然后遍历两棵树的子节点,每个接待你的对比过程和上面一样

    a.不过这里分两种情况,这里不细究

  3. 不过 React 加了 Fiber 架构,所以 React 的源码会更复杂

源码分析之「双端交叉对比」

React 的源码太难读懂,这里讲讲「Vue 双端交叉对比」,实现差不多的:

  • 头头对比:对比头部,如果找到,就把新节点 patch 到旧节点,头指针后移
  • 尾尾对比:对比尾部,如果找到,就把新节点 patch 到旧节点,尾指针前移
  • 旧尾新头:旧尾新头 交叉对比,如果找到,就把新节点 patch 到旧节点,旧尾指针前移,新头指针后移
  • 旧头新尾:旧头新尾 交叉对比,如果找到,就把新节点 patch 到就节点,新尾指针前移,旧头指针后移
  • key 对比:「一般是在最后,因为是最慢的,需要 n*n 的遍历」用新指针对应节点的key去旧数组寻找对应的节点,这里分三种情况,当没有对应的key,那么创建新的节点,如果有key并且是相同的节点,把新节点patch到旧节点,如果有key但是不是相同的节点,则创建新节点