我是在使用 JQuery 长大的,并且一直在遵循编程模式,可以说是“ React -like”,但不使用 React 。我想知道我的图形性能如何做得很好。
作为一个例子,在我的前端,我有一个表格显示一些“状态”(在 React 条款中)。然而,对我来说,这个“状态”只是保留在全局变量中。我有一个update_table()
函数,它是表的更新发生的中心位置。它采用“状态”并用它呈现表格。它做的第一件事就是调用$("#table").empty()
来获得一个干净的开始,然后用“状态”信息填充行。
我在服务器端每2-3秒有一些动态变化的数据(“状态”),我使用Ajax进行轮询,一旦得到数据/“状态”,我只需要调用update_table()
。
这是解决 React 的完美问题,我知道。但是,在使用JQuery实现这个简单的解决方案后,我发现它工作得很好(我没有在这里填充一个巨大的表;我最多有20行和5列)。
由于$("#table").empty()
调用,然后在update_table()
函数内逐个添加行,我预计会看到闪烁。然而,浏览器(chrome / safari)在某种程度上似乎做得很好,只更新了实际已经改变的元素(几乎就像浏览器有虚拟DOM /差异的实现一样,如 React !)
答案 0 :(得分:4)
我想您的问题是为什么没有React就可以拥有如此出色的图形性能。
你所看到的"良好的图形性能"真的是一个定义问题,或者更糟糕的是,意见。
经典的Netscape处理周期(所有现代浏览器都继承)基本上有四个主要阶段。 Here is the full-blown Gecko engine description
只要您操纵DOM,就可以进入" DOM更新"阶段并且不执行任何渲染。只有当你的代码产生时,下一个阶段才会开始。由于DOM的变化,一些元素的大小或位置也可能发生了变化。所以这个阶段重新计算布局。在此阶段之后,下一个是渲染,其中重新绘制像素。
这意味着如果您的代码更改了DOM中的大量元素,它们仍然一起呈现,而不是以增量方式呈现。因此,如果在之后立即重新填充表,则无法呈现empty()调用。
现在,当您看到像" 13872"这样的元素的像素时,渲染阶段可以使用完全相同的颜色渲染处于完全相同位置的像素。您的像素颜色没有任何变化,因此您无法看到闪烁。
那就是说,你的图形性能非常出色 - 是的。但是你是如何衡量它的?你只是看着它并决定它是完美的。现在,视觉上它真的可能非常好。因为您需要的只是避免布局阶段,不同的尺寸/定位。
但实际表现不是用我们人类懒惰的眼睛来衡量的(在那个领域有很多可用性研究,让我们说60Hz的一帧需要16.6毫秒,所以它足以渲染更少比起那个来说)。它使用实际指标(每秒更新或其他)来衡量。考虑到在使用旧版浏览器和速度较慢的显卡的旧机器上,您的优秀"表现可能看起来很可耻。你怎么知道它在64兆显存的旧东芝平板电脑上仍然不错?
那么缩放呢?如果你现在拥有100倍的元素,你确定它能够很好地扩展吗?如果某些数据占用更多(或更少)空间并更改整个布局会怎样?您的简单方法可能无法涵盖所有这些边缘条件。
像React这样的库会考虑到您可能还没有遇到的情况,并提供统一的模式来接近它们。
因此,如果您对您的解决方案感到满意,那么您就不需要React。我经常避免使用jQuery,因为ES5 / ES6现在已经相当不错了,我可以使用document.getElementById()等记下3-4行代码。但我意识到,在大型项目或复杂案例中,jQuery是完美的工具。
看看React就是这样的:当你意识到自己需要它时会很有用的工具,而当你认为自己可以做到这一点时很麻烦。这完全取决于你:)
答案 1 :(得分:2)
当你有这样的事情时:
$("#table").empty()
.html("... new content of the table ... ");
然后发生以下情况:
.empty()
删除内容并将渲染树/布局标记为无效。 .html()
添加新内容并将渲染树/布局标记为无效。 在调用InvalidateRect()(在Windows上)的其他内容中标记为无效,导致窗口在将来的某个时间点接收WM_PAINT事件。
通过处理WM_PAINT,浏览器将计算布局并呈现所有结果。
因此,多个更改请求将折叠为单个窗口绘制操作。