【问题标题】:GWT changing style during drag event takes too long拖动事件期间 GWT 更改样式花费的时间太长
【发布时间】:2013-08-07 13:18:47
【问题描述】:

这是我在这里的第一个问题,我不是英语母语人士,所以如果这让我的解释难以理解,我提前道歉。

上下文

我负责开发一个操作词汇集的小型应用程序。 该应用程序建立在 GWT 之上,由 GWT-Bootstrap 和其他一些库添加,与应用程序的 ui 部分无关。 为了向用户展示这个词汇的术语,我使用了一个树结构,从视觉上讲。

故事

树的要求很少,它必须允许其项目的拖放功能并显示它们之间的连接器。

我从使用原生 GWT 组件中的 Tree ui 类开始。事实证明,在树中加载了很多术语后,即使在生产模式下,性能也会下降。

我决定尝试 CellTree 实现,但它不适合我,因为让“showmore”按钮消失并不是一件容易的事,而且树的样式也是如此。

我终于从头开始实现了我自己的树实现。 这个实现本质上依赖于一个简单的 html 列表结构(ul-li),并且最大程度地受益于 css 功能。实际上,扩展树节点是通过 css 完成的,使用了一种称为“checkbox hack”的技巧。

此时树的自定义实现速度很快(比树或单元树更好),甚至填充了数千个项目,并且满足要求,但是...

问题

当一个项目被拖到其他项目上时,这些项目的样式会根据放置的可能性而改变。

第一种解决方案

第一个想法是利用 css,并使用 :hover 选择器来更改项目的样式,具体取决于它们的类。 但是在当前的浏览器(特别是 Chrome)中存在一个主要问题,如果鼠标左键按下,则不会触发 css :hover,当您拖动某些东西时就是这种情况(铬问题 122746)

似乎我不得不忘记一个专属的 css 解决方案,直到 :hover 触发问题将被关闭。

第二个解决方案

我得到的唯一其他解决方案是以编程方式更改项目的样式。

处理程序的代码

@Override
public void onDragEnter(DragEnterEvent event)
{
    if (event.getSource() instanceof Word)
    {
        event.stopPropagation();
        event.preventDefault();
        Word word = (Word) event.getSource();
        word.addStyleDependentName("over");
    }
}
@Override
public void onDragLeave(DragLeaveEvent event)
{
    if (event.getSource() instanceof Word)
    {
        event.stopPropagation();
        event.preventDefault();
        Word word = (Word) event.getSource();
        word.removeStyleDependentName("over");
    }
}

它适用于一些项目,但在处理数千个项目时,它会使应用程序冻结,并且呈现在某种程度上是随机的。

精度

在处理树中的 5000 个项目时出现问题(应用程序必须处理此类数据集)。

我知道有效的事件处理问题,例如事件冒泡,并且处理程序是唯一的,因为当潜在处理程序的数量(如果针对每个项目特定)是作为数量缺乏性能的因素时,建议使用它项目增加。

第二次我用测速仪分析了问题的根源,结果我不明白

事件在树的顶部元素上非常慢,特别是在样式重新计算后需要 1 秒才能触发的绘制事件 Slow events Speed Tracer Screenshot

事件速度在树的底部元素上是公平的 Fair enougth speed events Speed Tracer Screenshot

问题

几天以来我一直被这个问题困扰,我想知道是否有人能指出我所缺少的。 也许,这种行为是完全正常的,但也许有解决此类问题的方法? 如果有人能在这一点上帮助我,我会很高兴。

感谢您的回复!

lilBrain

【问题讨论】:

  • +1 格式精美
  • 你找到解决办法了吗?你有其他地方的示例代码吗?

标签: performance events gwt drag-and-drop tree


【解决方案1】:

如果您使用的是GWT-Dnd,请查看;

Slow drag performance when there are a lot of draggables on screen

提到这个性能问题与在放置事件中查找小部件的 x、y 坐标有关。

com.allen_sauer.gwt.dnd.client.DropControllerCollection.getIntersectDropController(int x, int y)

有一段代码循环通过 DropController 候选者,看起来它的唯一目的是用于调试。

for (int i = sortedCandidates.length - 1; i >= 0; i--) {
   Candidate candidate = sortedCandidates[i];
   if (DOMUtil.DEBUG) {
      DOMUtil.debugWidgetWithColor(candidate.getDropTarget(), "blue");
   }
}

在此之后,代码然后循环并实际尝试 确定 x 和 y 坐标是否在 DropController 上。

希望这会对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2014-10-01
    • 2021-08-02
    • 1970-01-01
    • 2014-02-16
    相关资源
    最近更新 更多