我在http://www.youtube.com/watch?v=x7cQ3mrcKaY看到一个React dev谈话,并且发言者提到模型的脏检查可能很慢 . 但是,由于虚拟DOM在大多数情况下应该大于模型,因此不计算虚拟DOM之间的差异实际上甚至更低性能吗?
我非常喜欢Virtual DOM的潜在力量(特别是服务器端渲染),但我想知道所有的优点和缺点 .
我在http://www.youtube.com/watch?v=x7cQ3mrcKaY看到一个React dev谈话,并且发言者提到模型的脏检查可能很慢 . 但是,由于虚拟DOM在大多数情况下应该大于模型,因此不计算虚拟DOM之间的差异实际上甚至更低性能吗?
我非常喜欢Virtual DOM的潜在力量(特别是服务器端渲染),但我想知道所有的优点和缺点 .
5 回答
Virtual Dom不是由反应发明的 . 它是HTML dom的一部分 . 它是轻量级的,与特定于浏览器的实现细节分离 .
我们可以将虚拟DOM视为React的HTML DOM的本地和简化副本 . 它允许React在这个抽象的世界中进行计算,并跳过“真正的”DOM操作,通常是缓慢的,特定于浏览器的 . 实际上,DOM和VIRTUAL DOM之间没有很大的区别 .
以下是使用Virtual Dom的原因(来源https://hackernoon.com/virtual-dom-in-reactjs-43a3fdb1d130):
以及更新DOM属性,即 . 值 . 它遵循一种算法 .
现在,假设您直接更新DOM 10次,那么上述所有步骤将逐个运行,更新DOM算法需要时间来更新DOM值 .
这就是Real DOM比虚拟DOM慢的原因 .
我是virtual-dom模块的主要作者,所以我或许可以回答你的问题 . 事实上,这里有两个问题需要解决
When do I re-render? 答:当我发现数据很脏时 .
How do I re-render efficiently? 答案:使用虚拟DOM生成真正的DOM补丁
在React中,每个组件都有一个状态 . 这种状态就像你可能在淘汰赛或其他MVVM风格的库中找到的一个可观察的状态 . 从本质上讲,React知道 when 重新渲染场景,因为它能够观察到这个数据何时发生变化 . 脏检查比可观察的慢,因为您必须定期轮询数据并以递归方式检查数据结构中的所有值 . 相比之下,在状态上设置值将向侦听器发出某个状态已更改的信号,因此React可以简单地侦听状态上的更改事件并排队重新呈现 .
虚拟DOM用于有效地重新呈现DOM . 这并不是因为计算两个虚拟树之间的差异有一些开销,但虚拟DOM差异是要了解DOM中需要更新的内容,而不是数据是否已更改 . 实际上, the diff algorithm is a dirty checker itself 但它用于查看DOM是否是脏的 .
我们的目标是仅在状态发生变化时重新渲染虚拟树 . 因此,使用observable检查状态是否已更改是防止不必要的重新渲染的有效方法,这会导致大量不必要的树差异 . 如果什么都没有改变,我们什么都不做 .
虚拟DOM很不错,因为它让我们编写代码就好像我们重新渲染整个场景一样 . 在幕后我们想要计算一个补丁操作,它可以更新DOM,看看我们的期望 . 因此,虽然虚拟DOM差异/补丁算法 is probably not the optimal solution ,它为我们提供了一种非常好的方式来表达我们的应用程序 . 我们只是声明我们想要的东西,React / virtual-dom将解决如何让你的场景看起来像这样 . 我们不必重新渲染整个场景,这可能比修补它的效率低得多 .
以下是React团队成员SebastianMarkbåge发表的评论,其中阐述了一些观点:
https://news.ycombinator.com/item?id=6937668
React不是唯一的DOM操作库 . 我鼓励您通过阅读article from Auth0来了解其他选择,其中包括详细的解释和基准 . 你会问:我会在这里强调一下它们的优点和缺点:
我最近在这里阅读了一篇关于React的diff算法的详细文章:http://calendar.perfplanet.com/2013/diff/ . 根据我的理解,React的快速之处在于:
批量DOM读/写操作 .
仅对子树进行高效更新 .
与脏检查相比,IMO的主要区别是:
Model dirty-checking :每当调用
setState
时,React组件都显式设置为脏,因此这里不需要比较(数据) . 对于脏检查,(每个模型的)比较总是发生在每个摘要循环中 .DOM updating :DOM操作非常昂贵,因为修改DOM也会应用和计算CSS样式,布局 . 从不必要的DOM修改中节省的时间可能比传播虚拟DOM所花费的时间长 .
第二点对于非平凡模型更为重要,例如具有大量字段或大列表的模型 . 复杂模型的一个字段更改将仅导致涉及该字段的DOM元素所需的操作,而不是整个视图/模板 .