为什么Reaction的虚拟DOM概念比肮脏的模型检查更具有性能呢?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (5)
  • 关注 (0)
  • 查看 (413)

我看到一个React开发人员在http://www.youtube.com/watch?v=x7cQ3mrcKaY演讲中提到,对模型的检查会很慢。但是,计算虚拟空间之间的差异和实际相比并不好,在大多数情况下,虚拟DOM应该比模型更大吗?

想知道VirtualDOM的优缺点。

提问于
用户回答回答于

以下是使用VirtualDOM的要点:

可以尝试使用:

document.getElementById('elementId').innerHTML = "New Value"

会发生以下情况:

  1. 浏览器需要解析HTML
  2. 它移除元素的子元素。
  3. 更新DOM值
  4. 重新计算父级和子级的css。
  5. 更新布局,即每个元素在屏幕上精确地协调。
  6. 遍历呈现树并在浏览器显示中绘制它。

重新计算CSS和更改布局使用复杂的算法,它们会影响性能,以及更新DOM属性(即值)。。

假设您直接更新DOM 10次,那么以上所有步骤都将逐一运行

这就是为什么RealDOM比虚拟DOM慢的原因。

用户回答回答于

React并不是唯一的DOM操作库。

React.js的虚拟DOM

优点

  • 快速高效的“diff”算法
  • 多态的(JSX,超文本)
  • 可移植性好
  • 独立性好

缺点

  • DOM的内存使用量较高
  • 静态元素和动态元素之间没有区别

Ember.js

优点

  • 快速高效的diff算法
  • 静态和动态元素的区分
  • 与Ember的API完全兼容
  • DOM的内存占用少

缺点

  • 只适用于Ember
  • 只有一个前端可用

增量DOM

优点

  • 内存使用量少
  • 简单的API
  • 易于与许多前端和框架集成

缺点

  • 运行速度较慢
  • 不方便分享
用户回答回答于

最近,我在这里阅读了一篇关于Reacti的diff算法的详细文章:http://caltim.perplanet.com/2013/diff/据我所知,快速渲染是因为:

  • 批处理DOM读/写操作。
  • 只对子树进行有效更新。

与Reacti检查相比区别:

1. 模型检查:当调用setState时,React组件被显式设置为dirty,因此这里不需要比较(数据)。对于脏检查,比较(模型)总是发生每个摘要循环。

2. DOM更新:DOM操作非常麻烦,因为修改DOM会影响CSS的布局。

第二点对特殊模型更重要,比如具有大量字段或大型列表的模型。复杂模型的一个字段更改只会导致涉及该字段的DOM元素所需的操作,而不是整个视图/模板。

用户回答回答于

事实上,这里有两个问题需要解决。

  1. 什么时候重新渲染? 答:当数据不纯净的时候
  2. 如何有效地重新渲染?答:使用虚拟DOM生成修复程序

在反应中,每个组件都有一个状态。这个状态就像你可以在淘汰赛或其他MVVM风格的库中看到的一样。本质上,反应知道何时重新渲染场景,因为它能够观察到数据何时发生变化。脏检查比可观察的要慢,因为您必须定期轮询数据,并递归地检查数据结构中的所有值。通过比较,在状态上设置一个值将向侦听器发送一些状态已经更改的信号,因此响应可以简单地侦听状态上的更改事件,并等待重新呈现。

虚拟DOM用于有效地重新呈现DOM。这与你的数据的脏检查无关。您可以使用虚拟DOM重新呈现,也可以不进行脏检查。您是正确的,在计算两个虚拟树之间的差异时存在一些开销,但是虚拟DOM diff是关于理解在DOM中需要更新什么,而不是您的数据是否发生了变化。实际上,diff算法本身就是一个脏的检查器,但是它是用来检查DOM是否脏的。

我们的目标是在状态改变时重新渲染虚拟树。因此,使用一个可观察到的方法来检查状态是否发生了变化,这是防止不必要的东西重新呈现的有效方法,这会导致许多不必要的树扩散。如果什么都没有改变,就不需要修改它。

虚拟DOM很好,因为它让我们编写代码,就像重新呈现整个场景一样。在幕后,我们希望计算一个补丁操作,更新DOM以查看我们的期望。因此,虽然虚拟DOM diff/patch算法可能不是最佳解决方案,但它提供了一种非常好的方式来表达我们的应用程序。我们只是声明了我们想要的,并且反应/虚拟dom将会解决如何让你的场景看起来像这样。我们不需要做手动DOM操作或先前的DOM混淆状态。我们不需要重新渲染整个场景,这可能比修补它的效率要低得多。

扫码关注云+社区

领取腾讯云代金券