虚拟DOM
约 647 字大约 2 分钟
2025-03-14
提问
- 什么是 Virtual DOM?
- 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 树上的节点。
