我正在使用 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);
}
这对我来说很有意义,因为 DOM 中的元素越多,计算绝对位置所需的时间就越多。但这令人沮丧,因为有时您只知道应用程序的一部分发生了变化,而这些方法仍然需要时间来计算绝对定位,可能是因为它不必要地重新检查了一大堆 DOM 元素。我的问题不一定是面向 GWT 的,因为它是与浏览器/javascript 相关的问题:
是否有任何已知的解决方案可以改善大型 DOM 元素应用程序的 GWT getAbsoluteLeft/javascript getBoundingClientRect 问题?
我在互联网上没有找到任何线索,但我想到了如下解决方案:
- (减少对这些方法的调用次数:-) ...
- 通过 iframe 隔离部分 DOM,以减少浏览器必须评估以获得绝对位置的元素数量(尽管它会使组件难以通信......)
- 同样的想法,可能有一些 css 属性(溢出,位置?)或一些 html 元素(如 iframe)告诉浏览器跳过 dom 的整个部分或只是帮助浏览器更快地获得绝对位置
编辑 :
使用 Chrome TimeLine 调试器,并在 DOM 中有很多元素时执行特定操作,我的性能平均:
- 重新计算样式:几乎为零
- 绘制:近 1 毫秒
- 布局:近900ms
通过 getBoundingClientRect 方法布局需要 900 毫秒。本页列出了 WebKit 中所有触发布局的方法,包括 getBoundingClientRect ...
由于 dom 中有许多不受我的操作影响的元素,我假设布局正在整个 DOM 中进行重新计算,而paint能够通过 css 属性/DOM 树来缩小其范围(我可以通过 Firebug 中的 MozAfterPaintEvent 看到它例子)。
除了对触发布局的方法进行分组和调用之外,关于如何减少布局时间的任何线索?
一些相关文章: