我正在使用 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 的整个部分,或者只是帮助浏览器更快地获得绝对位置
EDIT :
使用 Chrome TimeLine 调试器,并在 DOM 中有很多元素时执行特定操作,我的性能是平均的:
- 重新计算风格:几乎为零
- 绘制:近 1 毫秒
- 布局:近900ms
通过 getBoundingClientRect 方法布局需要 900ms。本页列表WebKit中所有触发布局的方法 http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html,包括 getBoundingClientRect ...
由于我的 dom 中有许多元素不受我的行为影响,我假设layout正在整个 DOM 中进行重新计算,而paint能够通过css属性/DOM树来缩小其范围(例如,我可以通过firebug中的MozAfterPaintEvent看到它)。
除了分组和少调用触发布局的方法外,关于如何减少布局时间的任何线索?
一些相关文章:
- 最大限度地减少浏览器回流 https://developers.google.com/speed/articles/reflow