什么是虚拟DOM?


140

最近,我查看了Facebook的React框架。它使用了一个我并不真正理解的概念,即“虚拟DOM”。

什么是虚拟DOM?有什么优势?


2
我相信虚拟DOM谈论的是不在普通DOM中的节点。
德里克·朕会功夫2014年

6
我同意上述关于节制的观点。此外,我认为这是一个非常有效和有用的问题。经常引用“虚拟DOM”,但很少定义。
btiernay 2015年

1
有限的网络经验让我无法理解,除非阅读scotch.io教程以开始使用。他们做得很好。
Rachael

Answers:


192

React创建了代表DOM一​​部分的自定义对象树。例如,它不是创建包含UL元素的实际DIV元素,而是创建包含React.ul对象的React.div对象。它可以非常快速地操作这些对象,而无需实际接触真正的DOM或通过DOM API。然后,当它渲染一个组件时,它使用这个虚拟DOM来弄清楚它需要与真实DOM做什么才能使两个树匹配。

您可以将虚拟DOM视为一个蓝图。它包含构造DOM所需的所有细节,但是由于它不需要进入真正DOM的所有重量级部件,因此可以更轻松地创建和更改它。


1
可以将它用于整个DOM,而不仅仅是一部分吗?
hipkiss16年

8
基本上是抽象之上的抽象,最后它做出什么反应在其对象模型树中寻找引用,选择html中的真实节点并对其进行修补。声音很棒virtual dom,但是没有花哨和夸张的感觉。
syarul

2
您的意思是“它不需要真正的DOM中的所有重量级部件”-重量级部件?
Ajay S

1
@AjayS操作真实的DOM并不是很有效,这就是为什么它被称为重型API。操作内存中的对象更快,更高效,更新已更改的DOM部分也更加高效,更快。
jcubic

43

让我们举个例子-一个非常幼稚的例子:如果您家里的房间里有东西弄乱了,需要打扫一下,那么第一步是什么呢?您会打扫房间还是整间房子?答案肯定是,您将只清洁需要清洁的房间。这就是虚拟DOM所做的。

普通JS遍历或呈现整个DOM,而不是仅呈现需要更改的部分。

因此,无论何时进行任何更改(例如要向<div>DOM中添加其他更改),都会创建虚拟DOM,而该虚拟DOM实际上不会对实际DOM进行任何更改。现在,使用此虚拟DOM,您将检查此虚拟DOM与当前DOM之间的区别。并且仅添加不同的部分(在本例中为new <div>),而不是重新渲染整个DOM。


21

什么是虚拟DOM?

虚拟DOM是对页面进行任何更改之前React组件生成的实际DOM元素的内存表示。

在此处输入图片说明

这是在调用渲染函数和在屏幕上显示元素之间发生的一步。

组件的render方法返回一些标记,但它不是最终的HTML。这是将成为真实元素的内存表示形式(这是步骤1)。然后,该输出将转换为真实的HTML,即在浏览器中显示的内容(这是第2步)。

那么,为什么要经历所有这些以生成虚拟DOM?简单的答案-这就是使反应迅速的原因。它通过虚拟DOM差异来做到这一点。比较两个旧的和新的虚拟树,并仅对实际DOM进行必要的更改。

来自Intro To React#2


17

一个virtual DOM(虚拟域)是不是一个新概念:https://github.com/Matt-Esch/virtual-dom

VDOM从战略上讲是在不重绘单个页面应用程序中所有节点的情况下更新DOM的。在树形结构中查找节点很容易,但SPA应用程序的DOM树可能非常庞大。在发生事件的情况下查找和更新一个或多个节点不是很节省时间。

VDOM通过创建实际dom的高标签抽象来解决此问题。VDOM是实际DOM的高级轻量级内存树表示。

例如,考虑在DOM中添加节点;反应在内存中保留VDOM的副本

  1. 创建具有新状态的VDOM
  2. 使用比较将其与较旧的VDOM进行比较。
  3. 仅更新真实DOM中的不同节点。
  4. 将新的VDOM分配为旧的VDOM。

7

这是对React JS经常提到的Virtual DOM的简短描述和重申。

DOM(文档对象模型)是结构化文本的抽象,这意味着它由HTML代码和CSS组成。这些HTML元素成为DOM中的节点。以前的操作DOM的方法存在局限性。虚拟DOM是在创建或使用React之前就创建的文字HTML DOM的抽象,但是出于我们的目的,我们将其与ReactJS一起使用。虚拟DOM轻巧,并且与浏览器中的DOM实现分离。虚拟DOM本质上是给定时间的DOM的屏幕快照(或副本)。从开发人员的角度来看,DOM是生产环境,而Virtual DOM是本地(开发)环境。每当React应用程序中的数据发生更改时,都会创建一个新的用户界面虚拟DOM表示形式。

在ReactJS中创建静态组件所需的最基本方法是:

您必须从render方法返回代码。您必须将每个类都转换为className,因为class是JavaScript中的保留字。除了较大的更改外,两个DOM之间还存在细微差别,其中包括出现在虚拟DOM中但不出现在HTML DOM中的三个属性(键,ref和dragonallySetInnerHTML)。

使用虚拟DOM时要了解的重要事项是ReactElement和ReactComponent之间的区别。

ReactElement

  • ReactElement是DOM元素的轻量,无状态,不可变的虚拟表示。
  • ReactElement-这是React中的主要类型,位于Virtual DOM中。
  • 可以将ReactElement渲染为HTML DOM

    var root = React.createElement('div'); ReactDOM.render(root, document.getElementById('example'));

  • JSX将HTML标记编译为ReactElements

    var root = <div/>; ReactDOM.render(root, document.getElementById('example'));

ReactComponent

  • ReactComponent-ReactComponent是有状态的组件。
  • React.createClass被认为是一个ReactComponent。
  • 每当状态更改时,都会重新渲染组件。

每当ReactComponent发生状态更改时,我们都希望对HTML DOM进行尽可能少的更改,以便将ReactComponent转换为ReactElement,然后可以将其插入到Virtual DOM中,进行比较和快速轻松地进行更新。

当React知道diff时-它会转换为在DOM中执行的低级(HTML DOM)代码。


3

这是一个简洁的概念:与其直接操作DOM(它容易出错,而且依赖于可变状态),而不是直接操作DOM,而是输出一个称为Virtual DOM的值。该虚拟DOM,然后显示差异与DOM,它产生的DOM操作,这将使当前的DOM看起来像新的列表的当前状态。这些操作可以快速批量应用。

这里拍摄


2

虚拟DOM是HTML DOM的抽象,它根据状态变化有选择地呈现节点的子树。它执行最少的DOM操作量,以使组件保持最新。


与抽象有什么关系?“抽象”一词在这里无关紧要
eladcm

0

虚拟Dom被创建为Dom的一个副本。将虚拟domdom进行比较,虚拟dom仅更新dom中已更改的部分。它并没有渲染整个dom,它只是更改了dom中dom的更新部分。这非常耗时,而且通过此功能,我们的应用可以快速运行。


0

所有的答案都很好。我只是想出了一个比喻,它可能会给出一个现实世界的隐喻。

真正的DOM就像您的房间,节点就是房间中的家具。虚拟DOM就像我们绘制当前房间的蓝图。

我们都有移动家具的经验,这非常累人(与更新计算机视图相同的概念)。因此,每当我们要更改位置/添加家具(节点)时,我们只想做非常必要的更改。

蓝图是为了实现这一目标而进行的救援。我们绘制了一个新的蓝图,并将其与原始蓝图进行比较。这使我们知道哪些部分已更改,哪些部分保持不变。然后,我们对实际房间进行必要的更改(更新真实DOM上已更改的节点)。欢呼。

(有些人可能会认为,为什么我们必须依靠虚拟的而不直接比较真实的DOM?嗯,以此类推,比较真实的DOM意味着您必须创建另一个真实的房间并将其与原始房间进行比较。 (太贵了。)


-1

让我们在这件事上有条理和合理。React(或任何其他库)是javascript上的“层”。

没有虚拟dom之类的东西,没有独立的dom。

让我用简单的javascript进行解释:

 let vDom = {};     // this is a object that will be used to hold the elements

 let d = document.createElement('div');
 d.innerHTML = 'hi, i am a new div';

 vDom['newDiv'] = d;

至此,我们创建了一个div,该div并未显示在dom上,因为它尚未连接

但是我们可以访问它,添加属性,值,更改等。

一旦我们调用:(例如,将其添加到正文中)

    document.body.appendChild(vDom['newDiv'])

然后我们将看到它;

 for one how saw javascript libs come and go , i suggest to any one 
 to do one simple thing : master JAVAscript, not layers :)

“没有虚拟dom这样的东西”-确实存在。这是React工作方式的核心特征。关于这个问题的公认答案可以很好地解释它。
昆汀
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.