虚拟DOM如何提高ReactJS的速度
How virtual DOM increases speed for ReactJS?
我读到ReactJS与其他框架相比非常快,因为它使用虚拟dom。
我不能理解的是,最终所有的框架都必须在浏览器中推送dom对象。虚拟dom如何帮助提高速度?
让我们说,如果我想添加10K节点列表,不应该需要DOM操作时间类似于ReactJS和其他框架?
每次对DOM进行增量更新或更改时,浏览器引擎都会占用更多内存和布局更改。因为它涉及到更多的几何和数学计算,这些计算是在浏览器上的每次布局变化中计算的。
然而,浏览器上的计算占用更少的内存,它不反映DOM上的任何东西。这种方法由VirtualDOM使用。
让我们以DOM为例,每个DOM都有自己的属性DOM属性,这些属性是模拟的(使用JS)。
虚拟DOM保留状态假设它有DOM的初始状态和所有属性
所以当有一个变化时,虚拟DOM不直接反映在DOM中,而是做比较操作或差异操作,这将只返回属性或属性从以前的状态改变
所以它只会更新DOM中改变的属性。而不是为了一个小的改变而重新绘制整个DOM。
这在频繁更新的web应用程序中非常有效,其中更改DOM的一小部分可以节省更多的内存或浏览器引擎的几何计算,而不是整个DOM部分。
ex: <DIV style="color:red; background-color:white;">Hello world <span>from Foo</span></DIV>
当我将文本改为Hello Mars时。而不是删除和创建一个新的DOM。
虚拟DOM只会改变DIV的文本,不影响子DOM的<span>
和其他属性
参见
- 浏览器如何工作浏览器如何绘制DOM
- 响应式编程。
首先,你必须记住DOM操作(重绘,回流)比Javascript操作要昂贵得多。
例如(人为的),更新
- live DOM元素可能花费3秒
- 虚拟DOM元素可能需要1秒
现在假设我有一个DOM
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
假设你想把它更新为
<ul>
<li>First Item</li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
如果没有虚拟dom,它将重新绘制屏幕上的所有6个元素,这将花费3x6=18秒
使用虚拟dom,我们可以在内存中绘制它,这将花费我们6秒。绘制完成后,我们可以比较发生了什么变化,在我们的例子中,1个元素——我们可以在3秒内绘制这个元素,所以我们在9秒内完成了这个操作(这比没有虚拟dom的时候要快)。
当然,您可以想象并不是所有的情况都能从虚拟dom中获益,但是在大多数情况下,使用虚拟dom是一个显著的改进。关键假设是实时DOM重绘/回流比虚拟DOM要昂贵得多。虚拟DOM在React中的工作是创建虚拟DOM树,在每个事件循环结束时,它会将当前的V-DOM树与之前的V-DOM树进行比较,然后获得补丁并操作真正的DOM。如果在一个事件循环中,用户多次修改同一个组件,React将计算最终结果并操作真正的DOM,这被称为"批处理"
所以实际上,并不是每个情况都能从react的V-DOM中获益。在你的例子中,React可能会使用innerHTML来操作真正的DOM。如果你频繁地改变其中一个元素,React会进行批处理。
你可以参考下面的文章http://calendar.perfplanet.com/2013/diff/
虚拟DOM是真正DOM的轻量级副本,它通过声明性API和diff算法比较那些需要在可观察对象的帮助下修改的元素,然后只重新绘制它们。而且,尽管每次都是从头开始创建虚拟DOM,但耗时不到50毫秒,这对人类的视觉感知来说是不明显的。这种技术有时会加快应用程序的性能,因为它不涉及不必要数量的真正DOM的"较重"元素,这些元素保留了它们的状态。
这是ReactJs快速的原因之一
- 如何在ReactJS JSX中执行嵌套的if-else语句
- 拨打'父亲'函数形式a'儿童'ReactJS中的组件
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 如何更改reactjs中外部/独立组件的状态或属性
- Wacom stu-430签名捕获速度太慢
- ReactJS和SpringDataRest缓存问题可能与websocket有关
- reactjs this.refs vs document.getElementById
- 如何在速度模板中获取LiferayPortlet实例id
- 同构reactjs-cdn资产
- 在ReactJS中重新渲染孩子3次可以接受吗
- 如何在ReactJs中显示Json数据
- 将IndexedDB中的数据拉入数组,并通过ReactJS输出
- 如何在ReactJs中渲染子组件时重新加载子组件的数据
- 如何在ReactJs中链接下拉列表和文本区域
- 我想放慢html中进程栏的速度
- 如何在ReactJs中呈现选定选项的更改表
- 在select上呈现不同形式的reactjs
- onClick事件未触发reactjs
- 如何在ReactJs中渲染重音符号
- 虚拟DOM如何提高ReactJS的速度