一篇文章弄懂虚拟DOM是什么
随着Web应用程序变得越来越复杂,管理用户界面的更新变得越来越具有挑战性。因此就诞生了虚拟 DOM(Virtual DOM) - 尤其是在 React 中。这是用于构建用户界面的领先的 JavaScript 库。
虚拟 DOM是在内存中对真实 DOM 的一种抽象表示。React 可以通过减少对真实 DOM 的直接操作来更有效地管理DOM的变化。这个过程大大提高了 Web 应用程序的性能。 理解虚拟 DOM 对于希望充分利用 React 的开发者至关重要。虚拟 DOM在 React 更新 UI 方面发挥着关键作用。通过使用虚拟 DOM,React 可以确保当用户界面(UI)发生变化时,只会对需要更新的部分进行实际渲染,而不必重新渲染整个界面。
在本文中,您将了解到:
- 什么是虚拟 DOM 以及它的工作原理
- 虚拟 DOM 与真实 DOM 的比较
- 使用虚拟 DOM 的好处
- React 如何使用虚拟 DOM
- 虚拟 DOM 与影子 DOM 的比较
- 关于虚拟 DOM 的常见误解
虚拟 DOM 是什么,它是如何工作的?
虚拟 DOM 是真实 DOM 元素在内存中的一种表示形式。React 不会直接操作真实 DOM,因为这样做可能会导致性能上的延迟和资源开销,而是创建了 UI 组件的虚拟表示。这个虚拟表示是一个轻量级的 JavaScript 对象,它模拟了真实 DOM 的结构。 以下是虚拟 DOM 工作的逐步过程:
步骤 1 - 初始渲染:当应用程序启动时,整个 UI 被表示为虚拟 DOM。React 元素被创建并渲染到虚拟结构中。 步骤 2 - 状态和属性的变化:随着应用程序中状态和属性的变化,React 在虚拟 DOM 中重新渲染受影响的组件。这些变化不会立即影响真实 DOM。 步骤 3 - 使用Diff(差异)算法进行比较:然后,React 使用Diff算法比较当前版本的虚拟 DOM 与先前的虚拟 DOM 。这个过程会识别出两个虚拟 DOM版本之间的差异。
步骤 4 - 协调过程:React 根据之前识别出的差异,决定了如何最有效地更新真实 DOM。这意味着只有需要更新的部分会被修改,而不是重新渲染整个用户界面,这样的选择性更新可以更快速、更高效。 步骤 5 - 更新真实 DOM:React 将根据步骤 3 中检测到的差异,将必要的更新应用到真实 DOM 上。这可能包括添加、删除或更新元素,以确保真实 DOM 与虚拟 DOM 保持同步。
例如,假设我们在 App 组件中实现了以下计数器功能:
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<h1>计数: {count}</h1>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
export default App;
上面示例的虚拟 DOM 的表示形式将如下所示:
{
"type": "div",
"props": {},
"children": [
{
"type": "h1",
"props": {},
"children": [
{
"type": "TEXT_ELEMENT",
"props": {
"nodeValue": "Counter: 0"
}
}
]
},
{
"type": "button",
"props": {
"onClick": "setCount(count + 1)"
},
"children": [
{
"type": "TEXT_ELEMENT",
"props": {
"nodeValue": "Increment"
}
}
]
}
]
}
当“增加”按钮被点击一次时,只有 h1 元素被改变,如下所示:
{
"type": "h1",
"props": {},
"children": [
{
"type": "TEXT_ELEMENT",
"props": {
"nodeValue": "计数: 1"
}
}
]
}
比较虚拟 DOM 和真实 DOM
要了解虚拟 DOM 的优势,重要的是要理解虚拟 DOM与真实 DOM 的区别。虽然真实 DOM 和虚拟 DOM 的目的相似,但二者的工作方式不同,这对性能和效率有重大影响。 真实 DOM 是浏览器中的内置标准接口,真实 DOM 既提供了一种结构化的方式来描绘 HTML 文档中的所有元素,也提供了操作HTML元素的方法。真实 DOM 涵盖了整个 HTML 文档的所有部分,从最开始的 Doctype 声明和根 html 元素,到文档中的每一个其他元素。
真实 DOM 将整个 HTML 文档表示为树形结构,并允许 JavaScript 操纵和更改 HTML 元素。有时,当某个HTML 元素发生变化时,整个文档可能都要重新渲染。
与真实 DOM 不同,虚拟 DOM 使用一种差异算法来比较 DOM 更新前的版本和更新后的版本。虚拟DOM只重新渲染 UI 中发生变化的部分,而不是整个页面。
在 Web 开发中使用虚拟 DOM 的好处
简化开发
虚拟 DOM 允许你以一种更高层次、更抽象的方式编写代码。你不需要详细地说明如何一步步地更新用户界面,而只需要描述界面最终应该是什么样子,然后 React 会根据你的描述自动处理具体的更新操作。这样可以使代码更简洁、更易于理解和维护。
提升性能
使用虚拟 DOM 的一个主要优势是显著的性能提升。直接操作真实 DOM 很慢,尤其是在复杂应用中可能导致性能问题。虚拟 DOM 减少了直接操作真实 DOM 的频率,从而提高了性能。如何理解这句中文的意思
增强用户体验
虚拟 DOM 确保了用户界面(UI)的更新更加平滑的、响应更加迅速,并且不会导致整个页面的刷新,从而提升了用户体验。用户很少会遇到延迟或卡顿,因此用户能够更流畅地与应用程序进行交互
跨平台开发
虚拟 DOM 的原理不仅限于 Web 开发。React Native——一个用于构建跨平台移动应用的 React 版本——采用了类似虚拟 DOM 的方法。这种开发方式使得开发者能够在 Web 和移动平台之间构建可以重用的代码,从而提高了生产力并减少了开发时间。
关于虚拟 DOM 的常见误解
有几个关于虚拟 DOM 的误解。我们看看其中的五个误解以及每个误解的现实情况。
虚拟 DOM 是浏览器的一个功能
实际情况:虚拟 DOM 是 React 实现的一种抽象,而不是浏览器的一个功能。浏览器拥有真实 DOM,这是表示和与 HTML 文档进行交互的标准方式。虚拟 DOM 仅存在于 React 内存中,用于优化和更新真实 DOM 。
虚拟 DOM 取代了真实 DOM
实际情况:虚拟 DOM 充当 React 和浏览器之间的中间层,而不是真实 DOM 的替代品。真实 DOM 仍然是浏览器用来渲染 UI 的方式,但真实DOM的更新由虚拟 DOM 管理。
React 是唯一使用虚拟 DOM 的库和框架
实际情况:React 仅仅是推广了虚拟 DOM 的概念,但并不是唯一使用虚拟 DOM的库或框架。其他框架如 Vue.js 和 Solid.js 也使用虚拟 DOM 来更新 UI。
虚拟 DOM 可以解决所有性能问题
实际情况:虚拟 DOM 可以显著改善性能,但并不能解决所有的性能问题。不良好的编码习惯、不必要的重新渲染以及庞大的组件树仍可能导致性能问题。
虚拟 DOM 和 影子 DOM 是相同的
实际情况:虚拟 DOM 和 影子 DOM 不是同一回事。虚拟 DOM 是真实 DOM 的抽象表示,用于优化 React 的 UI 更新。而 影子 DOM 是一种浏览器技术,用于封装 Web 组件的样式和结构。
真实 DOM vs 虚拟 DOM vs 影子 DOM
既然我们已经确定了虚拟 DOM、影子 DOM 和真实 DOM 是不同的。我们来看看三者之间的区别,详情见下面的表格截图:
结论
正如您在本文中所了解到的,虚拟 DOM 是 React 的一个关键特性,它提高了Web应用性能并实现了高效的 UI 更新。通过虚拟 DOM,React 能够将多个更新DOM的操作合并成一次批处理更新,从而减少了浏览器中的回流(reflow)和重绘(repaint)操作。这使得应用程序在更新 UI 时更加高效,同时能够有效地应用变化,提高了性能和用户体验。
理解虚拟 DOM 及其工作原理可以帮助您构建性能优异的 React 应用程序。
转载自:https://juejin.cn/post/7377589884188360714