2011-11-09 67 views
5

我正在使用GWT项目,我们正在使用FlexTable来显示一些数据。我知道我们可能应该使用CellTable,因为它具有更好的性能,但FlexTable更易于样式化(样式特定的单元格),并且更容易更新特定的单元格。GWT FlexTable性能和优化

要接收我们使用WebSockets的表的更新。我们现在面临的问题是当每秒通过WebSocket发送超过100次更新时,CPU负载过高。来自WebSocket连接的每条消息都包含表中几个单元格的更新。因此,实际上每秒钟应该在FlexTable中呈现超过100次更新。我的3GHz i5和4GB RAM的CPU负载约为50%。如果我禁用数据的实际渲染(注释掉setText()方法调用),那么CPU负载降至5-10%。所以我知道DOM更新是瓶颈,而不是代码的其他部分。

它会更好,以

  1. 使用网格而不是
  2. 开关CellTable(但如何让燎细胞更新即可)?
  3. 使用JS/JSNI与DOM的,而不是FlexTable的setText()工作

是否有实现表并提高性能更好的方法?

我试过谷歌,如果有人有与FlexTable类似的问题,但只发现一般意见,它只是缓慢,没有具体。我们有应用原型在JavaScript中,每秒钟CPU负载相同的100个更新纯粹做的是在15%左右

更新
删除我们用于指示在单元格的值降低CPU负荷变化的CSS淡入淡出效果〜10 %。所以看起来DOM并不是唯一的问题。

回答

0

作为一个替代方案(或者除了取决于你得到的结果之外),我会使用一些Scheduler方法来研究上述所有内容。尤其是Scheduler.get()。scheduleIncremental(),并且一次批量更新10个批次。这将允许浏览器在更新之间处理其他事件,并且应该对CPU使用率产生积极影响。

CellTable根本无法帮助您,因为您无法更新单个单元格。所以作为一个替代方案,它只会让您只有网格并手动管理TableElement。

+0

单元的实际更新是在SchedulerImpl.get()。scheduleDeferred()中完成的,但这并没有多大帮助。尽管它让浏览器更具响应能力。使用SchedulerImpl.get()。scheduleIncremental()不会工作,因为我们得到的数据量可能会有所不同。到目前为止,看起来我们应该尝试使用Grid或自己实现Table。 – dimchez

+0

在这种情况下,递增是远远好于延迟的。延迟将对每个操作使用新的js计时器,而增量会将多个更新批量处理到单个js执行堆栈中,从而导致单个页面重绘,从而允许渲染线程也批量执行操作。 – Ajax

2

使用CellTable,您必须重新渲染整个表以更新单个单元格。但是,这样的更新将是对DOM的单个更新。使用FlexTable,即使将所有更新批量加入到一起,您也会执行一系列单独的DOM操作。因此,即使使用CellTable看起来效率不高,因为您更新了一些单元格,但仍然值得切换。 特别是在更新接近单元总数的单元数量的情况下:批量100一起更新并一次完成一次DOM写操作。

我有一个CellTable的应用程序,可以像30x100一样大。它具有任意单元格的任意样式,每个单元格都有复杂的内容(一个<img>,一些<div>和一些文本),有时我需要更新单个单元格。重新绘制整个事情是不明显的(对我的人类看法)我的MacBook Pro在开发模式。

如果您想要实时更新(例如,每秒100次更新,当它们发生时),那么我认为您可能需要一个不同的平台。即使你的显示器每秒刷新100次。

+0

在某些情况下,我们可能在表中有100行,共有8列。其中6列用来自WebSocket提要的数据进行更新。在我们的模拟中,我们每10毫秒产生一条消息,总共给出100条消息,每秒600条DOM更新。这对FlexTable来说太多了。但很容易注意到数据更新迅速,因为它在不同的地方(单元格)进行了更新。一种最小化它的方法是使用JSNI并用一个DOM更新替换整行。但是,我不确定当代码从Java编译为JavaScript时,GWT不会做其他事情。 – dimchez

+0

你是说你想在100hz有一种闪闪发光的效果,更新发生在不同时间的不同地方?在这种情况下,我认为任何'

'结构都不适用 - 它的更新太多了。关于画布元素或Flash呢? –

+1

如果你不需要闪闪发光,并且只想一次更新所有100行,每秒一次,你应该完全使用'CellTable'。 –

0

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