在本文中,我们将尝试找出什么是 DOM 及其存在的问题。什么是 Virtual DOM,并解释它是如何解决真实 DOM 的问题的。

介绍

Facebook 开发人员创建的 React 引入了一个新术语,虚拟 DOM。虚拟 DOM 在大幅提高使用该库创建的应用程序的性能方面发挥着重要作用。在下文中,我们将定义虚拟 DOM 和真实 DOM,并解释虚拟 DOM 如何解决真实 DOM 的问题。

什么是 DOM

只是为了让事情变得简单 - DOM 代表文档对象模型,是结构化文本的抽象。它采用 HTML 元素并将它们包装在具有树结构的对象中——维护这些嵌套 HTML 元素的父/子关系。 HTML DOM 提供了一个接口 (API) 以多种方式遍历和修改Node——例如添加Node、删除Node、编辑Node的内容等。它包含 getElementById 或 removeChild 等方法。我们通常使用 JavaScript 语言来处理 DOM。 对其内部某些元素的任何操作都会导致完全重新渲染。随着越来越复杂的 Web 应用程序,这些真实 DOM 的完整呈现非常昂贵,导致应用程序性能下降。

DOM 的问题

DOM 操作是现代交互式网络的核心。但不幸的是,它也比大多数 JavaScript 操作慢很多。 如上所述,HTML DOM 始终是树形结构的——这是 HTML 文档的结构所允许的。这很棒,因为我们可以很容易地遍历树。不幸的是,在这里轻松并不意味着很快。由于大多数 JavaScript 框架对 DOM 的更新比它们必须做的多得多,因此这种缓慢变得更糟。 如今,DOM 树非常庞大。在单个 SPA(单页应用程序 - SPA)中拥有一千个Node是很常见的。由于我们越来越倾向于动态 Web 应用程序,因此我们需要不断地大量修改 DOM 树。像每次更改都重新绘制整个页面这样的低效更新非常昂贵,这是一个真正的性能和开发痛苦。

这正是 Virtual DOM 发挥作用的地方。

什么是虚拟 DOM

Virtual DOM 是真实 DOM 的轻量级抽象。您可以将其视为 DOM 的副本,可以在不影响实际 DOM 的情况下对其进行更新。 它由表示为树结构的真实 DOM 的两个副本组成。一个副本是真实 DOM 的精确副本,并保持不变,而另一个副本会随着对某些元素的操作而发生变化。在那一刻,两者进行比较并提取它们之间的变化。然后在真实 DOM 中实现提取的更改,而无需完全重新渲染。成功实施后,又有两个精确的副本。当对某个元素的操作再次发生时,该过程将重复。 它具有与真实 DOM 对象相同的所有属性,但没有像真实 DOM 那样写入屏幕的能力。虚拟 DOM 因其轻量级而获得了速度和效率。实际上,每次重新渲染后都会创建一个新的虚拟 DOM。

为了使真实和虚拟 DOM 保持同步,使用了一个名为 Reconciliation 的过程。差异算法是 React 使用的一种协调技术。

它如何解决问题?

当您在虚拟 DOM 中渲染元素时,每个虚拟 DOM 对象都会更新。 这听起来非常低效,但成本微不足道,因为虚拟 DOM 可以更新得如此之快。 一旦更新了虚拟 DOM,React 就会将虚拟 DOM 与更新之前拍摄的虚拟 DOM 快照进行比较。 通过将新的虚拟 DOM 与更新前的版本进行比较,React 可以准确地确定哪些虚拟 DOM 对象发生了变化。这个过程称为“差异化”。 一旦 React 知道哪些虚拟 DOM 对象发生了变化,React 就会在真实 DOM 上更新这些对象,并且只更新这些对象。在我们之前的示例中,React 足够聪明,可以重新构建一个已选中的列表项,而无需理会列表的其余部分。 这有很大的不同!React 只能更新 DOM 的必要部分。React 在性能方面的声誉主要来自这种创新。

总之,当您尝试在 React 中更新 DOM 时,会发生以下情况:

  1. 整个虚拟 DOM 得到更新。
  2. 将虚拟 DOM 与更新前的样子进行比较。React 计算出哪些对象发生了变化。
  3. 更改的对象,以及仅更改的对象,在真实 DOM 上得到更新。
  4. 真实 DOM 的变化会导致屏幕发生变化。

结论

Virtual DOM的创建解决了real DOM性能低、重渲染慢的问题。它使 Web 应用程序对用户来说更加复杂和更具交互性,而不必牺牲这么多的性能。