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

2024-05-15

我正在使用 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

我终于解决了我的问题:获取边界客户端矩形正在触发整个layout应用程序中的事件,该事件通过大量 CSS 规则花费了很多时间。

事实上,布局时间与 DOM 中元素的数量并不成正比。你可以用轻量风格绘制数十万个,布局仅需 2 毫秒。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大型应用的回流/布局性能 的相关文章

随机推荐