大型应用程序的回流/布局性能

JBE*_*JBE 2 html javascript gwt dom

我正在使用GWT来构建一个性能正常的HTML应用程序.

有时,它可以在DOM中加载许多对象,并且应用程序变得很慢.我使用Chrome开发者工具分析器来查看花费的时间(在应用程序编译后在Chrome下,即没有GWT开销),很明显方法getAbsoluteLeft()/ getBoundingClientRect()消耗了这段时间的主要部分.

以下是Chrome(com.google.gwt.dom.client.DOMImplStandardBase)下使用的实现:

private static native ClientRect getBoundingClientRect(Element element) /*-{
  return element.getBoundingClientRect && element.getBoundingClientRect();
}-*/;

@Override
public int getAbsoluteLeft(Element elem) {
  ClientRect rect = getBoundingClientRect(elem);
  return rect != null ? rect.getLeft()
     + elem.getOwnerDocument().getBody().getScrollLeft()
     : getAbsoluteLeftUsingOffsets(elem);
}
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义,因为DOM中的元素越多,计算绝对位置所需的时间就越多.但令人沮丧的是,因为有时你只知道你的应用程序的一个子部分已经改变了,而这些方法仍然需要时间来计算绝对定位,可能是因为它不必要地重新检查了一大堆DOM元素.我的问题不一定是面向GWT的,因为它是一个与浏览器/ javascript相关的问题:

有没有任何已知的解决方案来改善大型DOM元素应用程序的GWT getAbsoluteLeft/javascript getBoundingClientRect问题?

我没有在互联网上找到任何线索,但我想到的解决方案如下:

  • (减少这些方法的调用次数:-) ...
  • 通过iframe隔离DOM的一部分,以减少浏览器必须评估的元素数量以获得绝对位置(尽管它会使难以通信的组件......)
  • 在同样的想法中,可能有一些css属性(溢出,位置?)或一些html元素(如iframe)告诉浏览器跳过dom的整个部分或者只是帮助浏览器更快地获得绝对位置

编辑:

使用Chrome TimeLine调试器,并在DOM中有很多元素时执行特定操作,我有平均性能:

  • 重新计算风格:几乎为零
  • 油漆:接近1毫秒
  • 布局:近900ms

布局需要900毫秒通过getBoundingClientRect方法.此页面列出了在WebKit中触发布局的所有方法,包括getBoundingClientRect ...

由于我在dom中有许多不受我的操作影响的元素,我假设布局在整个DOM中进行重新计算,而paint可以通过css属性/ DOM树来缩小其范围(我可以通过firebug中的MozAfterPaintEvent看到它)例).

除了分组和调用触发布局的方法,有关如何减少布局时间的任何线索?

一些相关文章:

JBE*_*JBE 6

我终于解决了我的问题:getBoundingClientRect在应用程序中触发了一个完整的布局事件,这需要多次通过繁重的CSS规则.

实际上,布局时间与DOM中的元素数量不成正比.您可以使用轻型风格绘制数十万个,布局仅需2ms.

在我的例子中,我有两个CSS选择器和一个背景图像,它们匹配了数十万个DOM元素,这在布局过程中消耗了大量的时间.通过简单地删除那些CSS规则,我将布局时间从900ms减少到2ms.