什么是虚拟 Dom?为什么它更快?

2025-06-09

什么是虚拟 Dom?为什么它更快?

根据 React 文档,虚拟 DOM 是

虚拟 DOM (VDOM) 是一种编程概念,其中 UI 的理想或“虚拟”表示保存在内存中,并通过诸如 ReactDOM 之类的库与“真实” DOM 同步

在深入研究虚拟 DOM 之前,先简单介绍一下 DOM

文档对象模型 (DOM) 是构成 Web 文档结构和内容的对象的数据表示

DOM 本质上是 XML 和 HTML 等文档的树形结构表示。我们可以使用 DOM 来添加、删除或更新这些文档中的元素。

什么是虚拟 DOM?

虚拟 DOM 是 DOM 的一种表现形式。真实 DOM 的创建由浏览器处理。像 React、Vue 等现代框架会在内存中创建类似于真实 DOM 的元素树,这被称为虚拟 DOM。

例如:

<ul class="fruits">
    <li>Apple</li>
    <li>Orange</li>
    <li>Banana</li>
</ul>

上述代码可以在虚拟 DOM 中表示如下。

// Virtual DOM representation
{
  type: "ul",
  props: {
    "class": "fruits"
  },
  children: [
    {
      type: "li",
      props: null,
      children: [
        "Apple"
      ]
    },
    {
      type: "li",
      props: null,
      children: [
        "Orange"
      ]
    },
    {
      type: "li",
      props: null,
      children: [
        "Banana"
      ]
    }
  ]
}

为什么我们需要虚拟 DOM?

在早期 SPA 还不太流行的时候,渲染是在服务器端完成的。因此,对于每个用户交互/请求,服务器都会发送一个新的页面进行渲染。

对于 SPA 来说,只有一个文档,并且所有 DOM 操作都将在同一个文档中完成。因此,对于复杂的项目,可能会使用许多未优化的 DOM 操作。

例如:假设我们想从数组中呈现列表。我们可以像下面这样去做。

function generateList(fruits) {
    let ul = document.createElement('ul');
    document.getElementByClassName('.fruits').appendChild(ul);

    fruits.forEach(function (item) {
        let li = document.createElement('li');
        ul.appendChild(li);
        li.innerHTML += item;
    });

    return ul
}

let fruits = ['Apple', 'Orange', 'Banana']
document.getElementById('#list').innerHtml = generateList(fruits)

现在如果列表发生变化,可以再次调用上述方法来生成列表。

fruits = ['Pineapple', 'Orange', 'Banana']
document.getElementById('#list').innerHtml = generateList(fruits)

在上面的代码中,生成了一个新列表并将其设置在文档中。这种方法的问题在于,虽然只更改了单个水果的文本,但会生成一个新列表并将其更新到 DOM 中。此操作在 DOM 中运行缓慢。我们可以像下面这样修改未优化的代码。这将减少 DOM 中的操作次数。

document.querySelector('li').innerText = fruits[0]

未优化和优化代码的最终结果相同,但未优化的 DOM 操作会降低性能。如果列表很大,你就能看出区别。这正是我们在像 backbone.js 这样的老框架中遇到的问题。

所以回答我们的大问题“为什么我们需要虚拟 DOM?”是为了解决上述问题。

像 React 这样的现代框架的做法是,每当 state/props 发生变化时,就会创建一个新的虚拟 DOM 表示,并将其与之前的 DOM 表示进行比较。在我们的例子中,唯一的变化是将“Apple”更改为“Pineapple”。由于只更改了文本,而不是替换整个列表,因此 React 将通过以下代码更新 DOM。

document.querySelector('li').innerText = "Pineapple"

虚拟 DOM 比真实 DOM 快多少?

不,虚拟 DOM 并不比真实 DOM 快。虚拟 DOM 在底层也使用真实 DOM 来渲染页面或内容。因此,虚拟 DOM 不可能比真实 DOM 快。

那么为什么大家都说虚拟 DOM 更快呢?其实并不是虚拟 DOM 更快。通过使用虚拟 DOM,我们可以找出哪些内容发生了变化,并只将这些变化应用到真实 DOM 上,而不必替换整个 DOM。

虚拟 DOM 是减少昂贵的 DOM 操作的唯一方法吗?

不一定,其他框架如 ember js、angular 和 svelte 使用不同的方法来解决同一个问题。

结论

虚拟 DOM 是真实 DOM 的表示。每当状态发生变化时,都会创建新的虚拟 DOM 并将其与之前的虚拟 DOM 进行比较。然后,将针对这些特定的变化应用 DOM 操作。虚拟 DOM 的开销在于计算与另一个虚拟 DOM 的 diff。对于包含大量组件的大型项目,diff 计算会耗费时间。您可以点击此处了解更多关于如何处理这种情况的信息。

鏂囩珷鏉ユ簮锛�https://dev.to/karthikraja34/what-is-virtual-dom-and-why-is-it-faster-14p9
PREV
编写更好代码的工具
NEXT
让你的 PWA 在 iOS 上看起来更美观