Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么是React';s的虚拟DOM概念据说比脏模型检查更有效?_Javascript_Dom_Reactjs_Virtual Dom - Fatal编程技术网

Javascript 为什么是React';s的虚拟DOM概念据说比脏模型检查更有效?

Javascript 为什么是React';s的虚拟DOM概念据说比脏模型检查更有效?,javascript,dom,reactjs,virtual-dom,Javascript,Dom,Reactjs,Virtual Dom,我在()上看到了一个开发人员的演讲,演讲者提到对模型的脏检查可能会很慢。但是,由于虚拟DOM在大多数情况下应该比模型更大,所以计算虚拟DOM之间的差异的性能不是更差吗 我非常喜欢虚拟DOM的潜在功能(尤其是服务器端渲染),但我想知道所有的优点和缺点。我最近在这里读了一篇关于React的diff算法的详细文章:。据我所知,快速反应的原因是: 批处理DOM读/写操作 只对子树进行有效更新 与脏检相比,IMO的主要区别在于: 模型脏检查:只要调用setState,React组件就会显式设置为脏,因

我在()上看到了一个开发人员的演讲,演讲者提到对模型的脏检查可能会很慢。但是,由于虚拟DOM在大多数情况下应该比模型更大,所以计算虚拟DOM之间的差异的性能不是更差吗


我非常喜欢虚拟DOM的潜在功能(尤其是服务器端渲染),但我想知道所有的优点和缺点。

我最近在这里读了一篇关于React的diff算法的详细文章:。据我所知,快速反应的原因是:

  • 批处理DOM读/写操作
  • 只对子树进行有效更新
与脏检相比,IMO的主要区别在于:

  • 模型脏检查:只要调用
    setState
    ,React组件就会显式设置为脏,因此这里不需要比较(数据)。对于脏检查,(模型的)比较总是在每个摘要循环中进行

  • DOM更新:DOM操作非常昂贵,因为修改DOM还将应用和计算CSS样式、布局。不必要的DOM修改所节省的时间可能比扩散虚拟DOM所花费的时间更长


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

    以下是React团队成员Sebastian Markbåge的评论,其中透露了一些信息:

    React对输出(这是一种已知的可序列化格式,即DOM属性)进行diffing。这意味着源数据可以是任何格式。它可以是不可变的数据结构和闭包内部的状态

    角度模型不保持参照透明度,因此本质上是可变的。修改现有模型以跟踪更改。如果您的数据源每次都是不可变的数据或新的数据结构(例如JSON响应),该怎么办

    脏检查和Object.observe在关闭作用域状态下不起作用

    显然,这两件事对功能模式非常有限

    此外,当您的模型复杂度增加时,进行脏跟踪的成本会越来越高。但是,如果您只在可视化树上进行diffing,比如React,那么它就不会增长太多,因为您在任何给定点能够在屏幕上显示的数据量都受到ui的限制。Pete上面的链接涵盖了更多的性能优势


    我是模块的主要作者,因此我可能能够回答您的问题。事实上,这里有两个问题需要解决

  • 何时重新渲染?回答:当我观察到数据脏时
  • 如何高效地重新渲染?回答:使用虚拟DOM生成真实的DOM补丁
  • 在React中,每个组件都有一个状态。这种状态类似于在淘汰或其他MVVM样式库中可以看到的状态。本质上,React知道何时重新渲染场景,因为它能够观察此数据何时更改。脏检查比可观察的慢,因为您必须定期轮询数据,并递归检查数据结构中的所有值。相比之下,在状态上设置一个值将向侦听器发出某个状态已更改的信号,因此React可以简单地侦听状态上的更改事件并排队重新渲染

    虚拟DOM用于高效地重新呈现DOM。这实际上与脏检查数据无关。可以使用虚拟DOM重新渲染,可以使用脏检查,也可以不使用脏检查。您是对的,在计算两个虚拟树之间的差异时会有一些开销,但是虚拟DOM差异是关于了解DOM中需要更新的内容,而不是您的数据是否已更改。事实上,diff算法本身就是一个脏检查器,但它用于检查DOM是否脏

    我们的目标是仅在状态改变时重新渲染虚拟树。因此,使用可观察对象检查状态是否已更改是防止不必要的重新渲染的有效方法,这将导致大量不必要的树差异。如果什么都没有改变,我们什么也不做

    虚拟DOM很好,因为它允许我们编写代码,就像重新渲染整个场景一样。在幕后,我们希望计算一个补丁操作来更新DOM,使其符合我们的预期。因此,尽管虚拟DOM diff/patch算法可能不是最佳解决方案,但它为我们提供了一种非常好的方法来表达我们的应用程序。我们只需要准确地声明我们想要什么,React/virtualdom将解决如何使场景看起来像这样的问题。我们不必手动操作DOM,也不必对以前的DOM状态感到困惑。我们也不必重新渲染整个场景,这可能比修补它的效率要低得多

    我非常喜欢虚拟DOM的潜在功能(尤其是 服务器端渲染)但我想知道所有的优点和缺点

    --OP

    React不是唯一的DOM操作库。我鼓励您通过阅读本文来理解备选方案,其中包括详细的解释和基准。正如你所问,我将在这里强调他们的优点和缺点:

    React.js的虚拟DOM

    赞成的意见
    • 快速高效的“差分”算法
    • 多个前端(JSX、hyperscript)
    • 足够轻,可以在移动设备上运行
    • 大量的牵引力和分享
    • 可在无反应的情况下使用(即作为独立发动机)
    欺骗
    • DOM的完整内存拷贝(更高的内存使用)
    • 静态和动态元素之间没有区别
      document.getElementById('elementId').innerHTML = "New Value" Following thing happens: