React 或 Vue 的 DOM diff 算法是怎样的?

59 阅读1分钟

Dom diff 算法实际上就是新旧两颗虚拟 Dom 树进行对比,对比后会得出一个 patch ,依照这个去给真实 Dom 进行更新。 Diff 算法实际做了什么? i. 首先是先把根节点进行对比,比如 div 变成了 p,就认为整个树都变了,不在对比子节点,直接删除对应的真实Dom 树,再构建一个真实 Dom 树。 ii. 如果没有变化,就去对比根节点里的属性,如果没变就保留,如果变了就更新属性,不重新创建节点。在更新 Style 的时候,如果 css 一个属性变了,就只更新一个。 然后就按整个流程,去遍历子节点。 i. 情况一,

<ul>
  <li>A</li>
  <li>B</li>
</ul>

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

react 会依次对比,A-A , B-B, 空-C,最终会创建一个真实 C 节点插入页面 ii. 情况二

<ul>
  <li>B</li>
  <li>C</li>
</ul>

<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

B-A ,删除 B 生成一个 A;C-B 删除 C 生成一个 B;空-C 生成一个 C(这不是对比一个就生成一个真实 Dom 插入,而是放到 parch 里一起插入)。你可能会觉得这样效率很低,明明只用插入 A 就行了,这时候就需要 key 的出现了。

<ul>
  <li key="b">B</li>
  <li key="c">C</li>
</ul>

<ul>
  <li key="a">A</li>
  <li key="b">B</li>
  <li key="c">C</li>
</ul>

有了 key 就会发现 b,c 都在,新建一个 a 就可以了。 Vue 会比 react高效,因为他采用的双端交叉对比。 总结一下就是 4 个指针, 5 个步骤 头头对比 尾尾对比 旧尾新头 旧头新尾 最后对比 Key 这里讲的很详细,不翻墙可能会慢。我就不画蛇添足了。