此页内容

约 649 字大约 2 分钟

2022-04-21

提问

  1. 什么是 Virtual DOM?
  2. Virtual DOM 比 原生DOM快在哪里?

Virtual DOM

本质上,Virtual DOM 是一个普通的javascript对象。 我们将需要需要插入的文档的DOM树结构进行解析,使用一个对象结构进行表述, 比如一个元素对象,包含了 TagName , props , attribute ,children 等属性, 然后我们将这个对象结构保存起来,最后再将DOM片段插入到文档中。

当页面的状态发生变化,需要对页面的DOM结构进行调整的时候,首先根据变更的状态,重新构建一颗对象树, 然后将新的对象数和旧的对象数进行对比,记录下两颗树的差异,最后将有差异的地方应用到DOM树中,视图就实现了更新。

Virtual DOM 比 原生DOM快在哪里?

首先,Virtual DOM 本身并没有比原生DOM直接操作DOM要快,但是 Virtual DOM 这种方法对于需要进行大量的DOM操作, 操作颗粒比较细、多、复杂的场景下,能够很好的提高操作效率。

通过在操作DOM前,通过 Diff 算法对比新旧两个Virtual DOM,我们可以 确定最小的更新范围,尽可能的减少DOM操作带来的回流和重绘的影响。

其目的是是提高了我们的开发时的可维护性,在任意情况下,都能保证在 Virtual DOM 带来的尽量小的性能消耗操作DOM。

DOM 树的比较

两个树的完全 diff 算法的时间复杂度为 O(n^3) ,但是在前端中,我们很少会跨层级的移动元素,所以我们只需要比较同一层级的元素进行比较,这样就可以将算法的时间复杂度降低为 O(n)。

算法首先会对新旧两棵树进行一个深度优先的遍历,这样每个节点都会有一个序号。在深度遍历的时候,每遍历到一个节点,我们就将这个节点和新的树中的节点进行比较,如果有差异,则将这个差异记录到一个对象中。

在对列表元素进行对比的时候,由于 TagName 是重复的,所以我们不能使用这个来对比。我们需要给每一个子节点加上一个 key,列表对比的时候使用 key 来进行比较,这样我们才能够复用老的 DOM 树上的节点。