GWT在拖动事件期间更改样式太慢了。

4
这是我在这里的第一个问题,我不是英语母语者,所以如果我的解释难以理解,请提前谅解。
上下文:
我负责开发一个操作词汇集合的小型应用程序。该应用程序基于GWT构建,添加了GWT-Bootstrap和其他一些与应用程序UI无关的库。为了向用户展示这个词汇表的术语,我使用了一个树形结构,从视觉上讲。
故事:
这棵树有几个要求,它必须允许对其项目进行拖放功能,并显示它们之间的连接器。
我开始使用本机GWT组件中的Tree UI类。结果证明,当树中加载了大量术语时,性能下降了,即使在生产模式下也是如此。
于是,我决定尝试CellTree实现,但它并不适合我,因为让“showmore”按钮消失并不是一件容易的事情,而且还需要为树设置样式。
最终,我从头开始自己实现了一棵树。这个实现基本上依赖于一个简单的HTML列表结构(ul-li),并充分利用了CSS的功能。确实,扩展树节点是通过CSS完成的,使用一种称为“复选框hack”的技巧。
到这一点为止,树的自定义实现很快(比树或celltree更好),即使填充了数千个项目,也满足了要求,但是……
问题:
当一个项目被拖动到其他项目上时,这些项目的样式会根据放置可能性而改变。
第一个解决方案:
第一个想法是利用CSS,并使用:hover选择器根据它们的类更改项目的样式。但是当前浏览器存在一个主要问题(特别是Chrome),如果鼠标左键按下(在拖动某物时是这种情况),则不会触发CSS:hover(chromium issue 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秒钟才能触发 缓慢事件速度跟踪器截图

底部元素的事件速度是足够快的 足够快的事件速度跟踪器截图

问题

我已经被这个问题困扰了几天,想知道是否有人能指出我缺少什么。 也许这种行为完全正常,但也许有解决此类问题的方法? 如果有人能在这一点上帮助我,我将不胜感激。

非常感谢您的回复!

lilBrain


1
漂亮的格式+1. - d-stroyer
你找到任何解决方案了吗?你有其他地方的示例代码吗? - Fedy2
1个回答

2
如果您正在使用GWT-Dnd,请查看以下内容:http://code.google.com/p/gwt-dnd/当屏幕上有大量可拖动对象时,拖动性能变慢 据提到,这个性能问题与在放置事件中查找小部件的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");
   }
}

在那之后,代码会循环执行并尝试识别是否超过了DropController的x和y坐标。

希望这可以帮到你。


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