3

我是使用JQuery长大的,并且一直遵循一种可以说是“类似React ”但不使用React的编程模式。尽管如此,我还是想知道我的图形性能表现如何。

例如,在我的前端,我有一个显示一些“状态”的表格(用React术语)。但是,对我来说,这个“状态”只是保存在全局变量中。我有一个update_table()函数,它是发生表更新的中心位置。它采用“状态”并用它呈现表格。它做的第一件事是调用$("#table").empty()以获得一个干净的开始,然后用“状态”信息填充行。

我在服务器端每 2-3 秒有一些动态变化的数据(“状态”),我使用 Ajax 进行轮询,一旦我得到数据/“状态”,我就调用update_table().

我知道,这是用React解决的完美问题。然而,在用 JQuery 实现这个简单的解决方案之后,我发现它工作得很好(我没有在这里填充一个巨大的表;我最多有 20 行和 5 列)。

我希望看到闪烁,因为调用之后在函数$("#table").empty()内逐一添加行。update_table()但是,浏览器(chrome/safari)似乎在仅更新实际更改的元素方面做得非常好(几乎就像浏览器具有虚拟 DOM/diffing 的实现,如React!)

4

2 回答 2

4

我想你的问题是为什么没有 React 可以有这么好的图形性能。

您所看到的“良好的图形性能”实际上是定义问题,或者更糟糕的是意见问题。

经典的 Netscape 处理周期(所有现代浏览器都继承)基本上有四个主要阶段。这是完整的 Gecko 引擎描述

只要您操作 DOM,您就处于“DOM 更新”阶段,根本不会执行任何渲染。只有当您的代码产生时,下一阶段才会开始。由于 DOM 的变化,某些元素的大小或位置也可能发生了变化。所以这个阶段重新计算布局。在这个阶段之后,接下来是渲染,重新绘制像素。

这意味着如果您的代码更改了 DOM 中的大量元素,它们仍然会一起呈现,而不是以增量方式呈现。因此,如果您之后立即重新填充表,则不会呈现 empty() 调用。

现在,当您看到像“13872”这样的元素的像素时,渲染阶段可能会以完全相同的颜色渲染位于完全相同位置的像素。像素颜色没有任何变化,因此看不到闪烁。

也就是说,您的图形性能非常出色——是的。但是你是怎么测量的呢?你只是看着它并决定它是完美的。现在,在视觉上它真的可能非常非常好。因为您所需要的只是避免布局阶段以不同的方式调整大小/定位。

但是实际性能不是用我们人类懒惰的眼睛来衡量的(在那个领域有很多可用性研究,假设 60 Hz 的一帧需要 16.6 毫秒,所以在不到这个范围内渲染就足够了)。它是用实际指标(每秒更新或其他)来衡量的。考虑到在具有较旧浏览器和较慢图形卡的较旧机器上,您的“出色”性能可能看起来很可耻。您怎么知道它在具有 64 MB 显存的旧东芝平板电脑上仍然不错?

那么缩放呢?如果你拥有的元素是现在的 100 倍,你确定它会很好地扩展吗?如果某些数据占用更多(或更少)空间并改变整个布局怎么办?您的简单方法可能无法涵盖所有​​这些边缘条件。

像 React 这样的库考虑了你可能还没有遇到过的那些情况,并提供了一个统一的模式来处理它们。

所以如果你对你的解决方案感到满意,你就不需要 React。我经常避免使用 jQuery,因为这些天 ES5/ES6 已经相当不错了,我可以使用 document.getElementById() 等记下 3-4 行代码。但我意识到,在较大的项目或复杂的情况下,jQuery 是完美的工具。

像这样看待 React:当你意识到你需要它时它是有用的工具,当你认为你可以不用它时它就很麻烦。全取决于你 :)

于 2016-04-15T21:12:15.403 回答
2

当你有这样的事情:

$("#table").empty()
           .html("... new content of the table ... ");

然后发生以下情况:

  1. .empty()删除内容并将渲染树/布局标记为无效。
  2. .html()添加新内容并将渲染树/布局标记为无效。

标记为无效调用InvalidateRect()(在 Windows 上),这会导致窗口在将来的某个时间点接收WM_PAINT事件。

通过处理 WM_PAINT 浏览器将计算布局并呈现所有结果。

因此,多个更改请求将被折叠为单个窗口绘制操作。

于 2016-04-15T21:17:12.133 回答