为什么使用虚拟 DOM?

2025-06-08

为什么使用虚拟 DOM?

插件:我帮助开发million:<1kb 虚拟 DOM - 它很快!

介绍

虚拟 DOM 最初是由 React 作者在提高 JavaScript 声明式模式性能的基础上提出的——但是它是如何实现的呢?为了理解这一点,我们需要快速回顾一下传统 DOM 操作的工作原理。

一般来说,更改 DOM(“修改 HTML”)最简单的方法是改变innerHTML元素的属性。例如,如果我想div在文档主体中添加一个元素,我可以这样做:

document.body.innerHTML = '<div>Hello World!</div>';
// <body> now has a <div>Hello World!</div> child.
Enter fullscreen mode Exit fullscreen mode

这看似计算性能良好,实则不然。虽然重新赋值操作计算性能良好,但 DOM 重绘(“更新用户所见内容”)却并非如此。这是因为innerHTML需要从字符串解析 DOM 节点,进行预处理并附加,导致性能不佳。当子元素/属性较多且突变间隔较短时,性能问题会更加明显。

那么,这个问题该如何解决呢?答案是,我们会精确定位 DOM 的变化。例如,这个解决方案比之前的方案快了近 10 倍innerHTML

const div = document.createElement('div');
div.textContent = 'Hello World!';
document.body.appendChild(div);
Enter fullscreen mode Exit fullscreen mode

虽然这很简单,但一旦开始执行连续的变更,就会变得更加复杂。这就是虚拟 DOM 诞生的原因——它允许你编写声明性内容(例如示例中的字符串innerHTML),同时通过仅对 DOM 进行精确的更改来提升性能。

虚拟 DOM

虚拟 DOM 是一个虚拟节点树,它代表了 DOM 的外观。虚拟节点是轻量级的、无状态的,并且是仅包含必要字段的 JavaScript 对象。虚拟节点可以组装成树,并通过“差异化”对 DOM 进行精确更改。

虽然这种方法很高效,但也有一些需要注意的地方。值得注意的是,差异化计算并非零计算。遍历树具有O(n^3)时间复杂度,这意味着子节点越多,执行操作所需的时间就越长。为了解决这个问题,Million 应运而生。

如果您不了解虚拟 DOM 是什么,请阅读本文。

百万

Million 提供了五项主要改进:粒度修补、更少的迭代过程、快速文本插值、键控虚拟节点、编译器标志。

  • 细粒度修补:当 props 或子项出现差异时,不是仅仅替换整个元素,而是只更改必要的 props。
  • 更少的迭代次数:百万次尝试减少差异分析期间的次数,从而实现更好的时间和空间复杂度。
  • 快速文本插值: Million 不使用 DOM 方法替换文本节点,而是使用编译器标志来设置textContent元素以提高性能。
  • 键控虚拟元素:如果新的虚拟元素键与旧的虚拟元素键相同,则修补算法可以跳过节点,从而最大限度地减少不必要的工作量。
  • 编译器标志:这允许修补算法跳过条件分支,这意味着完成的工作更少。


感谢阅读!欢迎给Million点个星,或者关注/评论这篇文章,获取更多 Virtual DOM 内容!

鏂囩珷鏉ユ簮锛�https://dev.to/aidenybai/why-is-the-virtual-dom-necesssary-59l2
PREV
使用 Github Actions 搭建番茄钟!我的工作流程 pomodoro-clock
NEXT
使用 Rest API、Spring Boot、Maven 和 Fauna 构建任务管理应用程序