GWT FlexTable性能和优化

5
我正在开发一个GWT项目,我们使用FlexTable来显示一些数据。我知道我们应该使用CellTable,因为它具有更好的性能,但是FlexTable更容易进行样式设计(样式特定单元格),并且使得更新特定单元格更加容易。
为了接收表格更新,我们使用WebSockets。我们现在面临的问题是,当每秒钟有超过100个更新通过WebSockets传递时,CPU负载很高。每个WebSocket连接的消息包含表格中多个单元格的更新。因此,在实践中,应该呈现超过100次每秒的更新到FlexTable中。我的3GHz i5处理器和4GB RAM内存的CPU负载约为50%。如果我禁用实际数据的呈现(注释掉setText()方法调用),那么CPU负载将下降至5-10%。因此,我知道DOM更新是瓶颈,而不是代码的其他部分。
是否最好:
  1. 使用Grid代替
  2. 切换到CellTable(但如何进行单个单元格更新)?
  3. 使用JS / JSNI处理DOM,而不是FlexTable setText()

有更好的实现表格和提高性能的方法吗?

我尝试在谷歌上搜索是否有人遇到过FlexTable类似的问题,但只发现普遍意见认为它很慢,没有具体的解释。我们的应用程序原型完全使用JavaScript完成,每秒相同的100次更新时,CPU负载约为15%

更新
放弃我们用来指示单元格值变化的css淡入效果可以将CPU负载降低约10%。因此,DOM不是唯一的问题。

3个回答

2
使用CellTable时,您必须重新渲染整个表格以更新单个单元格。但是,这样的更新只会导致对DOM进行一次更新。使用FlexTable时,即使将所有更新批处理在一起,仍然需要执行大量单独的DOM操作。因此,即使使用CellTable会导致一些单元格冗余更新,看起来效率低下,切换到CellTable仍然可能是值得的。特别是在更新的单元格数量接近总单元格数的情况下:将100个更新批处理在一起并一次性执行它们,以进行单个DOM写入。
我有一个应用程序,其中包含大小可达30x100的CellTable。每个单元格都具有任意样式,每个单元格都具有复杂的内容(一个,一些
和一些文本),有时需要更新单个单元格。在我的开发模式的MacBook Pro上,重新绘制整个表格对我来说无法察觉。
如果您想要实时更新(例如每秒100次更新),那么我认为您可能需要不同的平台。甚至您的显示器也不会每秒刷新100次。

在某些情况下,我们的表格中可能有100行,每行有8列。其中6列会从WebSocket feed中更新数据。在我们的模拟中,我们每10毫秒生成1条消息,总共每秒产生100条消息,600个DOM更新。这对于FlexTable来说太多了。但很容易注意到数据被快速更新,因为它在不同的位置(单元格)上更新。一种最小化更新的方法是使用JSNI,并用一个DOM更新替换整行。但我不确定当Java编译成JavaScript时,GWT是否会执行其他操作。 - dimchez
你是说你想要一个在100hz下闪烁的效果,更新在不同的时间发生在不同的地方?如果是这样,我认为任何<table>结构都不合适 - 它需要太多的更新。那么使用canvas元素或Flash怎么样? - Riley Lark
1
如果您不需要闪烁效果,只想每秒一次地更新所有100行数据,那么您应该完全使用CellTable - Riley Lark
不,我们需要能够独立更新每个单元格(最好的情况)。JavaScript原型能够在同一台机器上仅使用10-15%的CPU负载处理相同的100条消息每秒。因此,我知道这应该是可能的。我只需要找到在GWT中实现它的最佳方法。CellTable似乎不是最佳选择。 - dimchez

0

你可以使用cellTable.redrawRow(index);,这在大表格上更快。
好的是,行索引由FieldUpdater给出。


0

除了上述方法之外(或者作为补充,根据您得到的结果而定),我建议您考虑使用一些调度程序方法。特别是Scheduler.get().scheduleIncremental(),每次以10个为一批进行更新。这将允许浏览器在更新之间处理其他事件,并对CPU使用率产生积极影响。

CellTable在这里无法帮助您,因为您无法更新单个单元格。所以作为替代方案,只剩下Grid和手动管理TableElement。


实际单元格的更新是在SchedulerImpl.get().scheduleDeferred()内完成的,但这并没有太大帮助。虽然它可以使浏览器更加响应。使用SchedulerImpl.get().scheduleIncremental()将不起作用,因为我们获取的数据量可能会有所变化。到目前为止,看起来我们应该尝试Grid或自己实现Table。 - dimchez
在这种情况下,增量式明显比延迟式更好。延迟式将为每个操作使用一个新的js计时器,而增量式将多个更新批处理到单个js执行堆栈中,从而导致单个页面重绘,允许渲染线程也批量执行操作。 - Ajax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接