【问题标题】:How React.js speeds up rendering with a virtual DOMReact.js 如何使用虚拟 DOM 加速渲染
【发布时间】:2016-09-06 16:59:12
【问题描述】:

引用这篇(https://news.ycombinator.com/item?id=9155564)文章

简短的回答是 DOM 并不慢。添加和删​​除 DOM node 是几个指针交换,只不过是设置一个属性 on JS 对象。

DOM 瓶颈仅仅是那些导致重绘的东西吗?如果是这样,那么来自 React 的虚拟 DOM 的渲染不应该与重绘整个组件(当然是在一个浏览器 API 调用中)具有相同的性能吗?我认为浏览器执行的算法只会尝试将差异从一种状态重绘到另一种状态(可能像 git?)。暗示浏览器自己维护一个虚拟 DOM。那么,拥有一个虚拟 DOM 有什么意义呢?

还应该添加一个将display 样式属性设置为none 的元素不会严重影响性能吗?我自己会对此进行分析,但由于我最近才开始进行 javascript 编程,所以我不知道该转向哪里。

【问题讨论】:

  • 如果你只画一次,没有什么是慢的。
  • 这就是我想问的问题,如果您使用虚拟 DOM($().prepend 或 $.append())而不是 n 浏览器 API 渲染 n 次调用差异应该很大吗?
  • 它在需要时添加或附加,并且只需更改属性或仅更改其后代之一,这一切都基于数据的更改方式和差异算法
  • 如果 chrome 这样做,那将是个大新闻。
  • @YOU 没关系!如果是给你的公司,我可能没有生意看它!我只是好奇而已。不过谢谢!

标签: javascript jquery html dom reactjs


【解决方案1】:

问: “DOM 瓶颈是否只是那些导致重绘的东西?”


答: 重绘取决于 GPU。与 od DOM 更新的速度无关。 DOM 更新几乎是即时的。 一切都取决于影响文档流的更改。如果某个 DOM 或 DHTML 更改影响了文档流。受影响的元素越靠近文档元素的根,对文档重排的影响就越大。

您无需更改 DOM 内容即可导致文档重排。给定参数上的简单样式属性更改可能会推动流的元素更改位置,从而导致强制文档重排。

因此,不,固定大小元素上的 DOM 更改不会导致文档重排,而显示的更新实际上是即时的。将仅应用于局部受影响的区域,大部分时间在可能小于 300 x 200 像素正方形的帧中;可以在非常慢的 GPU 上以超过 120fps 的速度重绘的区域大小。但这比在电影院看复仇者联盟要流畅 5 倍。

( 流对齐内容的任何空间非等效变化都会导致重排。所以我们必须注意影响浮动元素大小和位置的变化,另一个内联元素的长流中内联元素的变化等等)

'


问: “是否应该添加一个将显示样式属性设置为 none 的元素不会严重影响性能?”


答: 这是正确的。将 style.display: "none" 元素添加到 DOM 不会导致文档的现有渲染发生变化,因此不会触发文档重排,自然不会影响全部;即:将与向 JavaScript 对象添加新属性一样快。

问候。

【讨论】:

    【解决方案2】:

    这个问题对于 SO 来说可能有点宽泛,但作为一般性答案,同一篇文章中的一些其他引用也非常相关:

    但是,布局很慢...
    [...]
    更糟糕的是,布局是通过访问某些属性同步触发的...
    [...]
    正因为如此,很多 Angular 和 JQuery 代码都非常慢
    [...]
    React 无助于加快布局...

    react 的虚拟 DOM 所做的是计算 DOM 的一个状态与下一个状态之间的差异,并以一种非常智能的方式最小化 DOM 更新

    所以:

    • DOM 本身并不慢
    • 但布局很慢
    • 几乎所有 DOM 更新都需要布局更新
    • 所以更少的 DOM 更新速度更快

    React 引擎就是这样做的(与其他几个具有虚拟 DOM 的工具/库相同)。

    关于什么是虚拟 DOM 及其优势的更多信息,例如here.

    【讨论】:

    • 是的!我明白,但如果说我有一个包含页面所有 html 的 div,然后我会完全更新该 div。这也是一个更新。如果 react 去计算差异本身。那也只是一次更新。是什么阻止了浏览器自己计算新旧状态之间的差异?
    • 通常,<div> 包含一个非常精细的 HTML 树,其中包含许多元素。如果您替换整个树,那 1 个更新实际上会解压缩为数千个子更新。 react 所做的只是进行必要的子更新。如果你替换整个树,并且每个子组件也不同,那么 react 的差异引擎就没有效果。但在现实生活中,这种情况几乎从未发生过。 AFAIK 浏览器不像反应那样做差异。我猜是什么“阻止”它们是浏览器开发团队开发优先级的问题。
    猜你喜欢
    • 2014-10-08
    • 2014-09-27
    • 2018-07-01
    • 1970-01-01
    • 2016-01-09
    • 2021-09-14
    • 2020-05-14
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多