如何判断浏览器何时停止重新绘制DOM图层/节点,因为它们被遮挡了?

时间:2014-01-29 17:08:55

标签: javascript performance dom javascript-events requestanimationframe

鉴定 我正在寻找所有可能的解决方案,用于检测由于浏览器优化性能而导致浏览器中FPS掉落或重新绘制/回流停止发生的时间,因为文档区域不在视野范围内。

观察: 到目前为止,我研究过的大多数原生HTML / JS解决方案都没有考虑到DOM的部分,这部分已经被页面的其他部分所掩盖,或者是低于首屏的DOM。虽然有时内容将直接嵌入父文档中,但有时可能在框架或iframe中。

测试结果: mozPaintCount 是窗口dom回流的精确表示,当窗口或框架中的文档被遮挡时,它会正确响应。似乎Firefox正确识别dom的一部分而不是在它们被遮挡时重新绘制它们,当某些东西不在视野中时可以通过firefox检查器工具进行目视检查,但是检查员在绘制时可能不会考虑视图层次结构。重新粉刷区域的亮点。感谢你,Mozilla!

参考:mozPaintCount

Flash还显示FPS在屏幕外时速度减慢,而最新的 Flash Player 11.2 有一个专用事件,当出于优化原因被浏览器限制时会触发该事件。 Flash也不是值得信赖的解决方案,因为它在许多浏览器中默认禁用。

参考:Flash Player 11.2 Throttle Events

页面可见性更改事件的当前浏览器实现能够在窗口更改为另一个选项卡时进行广播,或者窗口变为非活动状态,但不考虑折叠下方的元素/窗口/文档的滚动位置或被其他dom遮挡。但是,在本规范的第二稿中,已经建议浏览器考虑视口和DOM层次结构以提供更准确的结果。

参考文献:Recommendation Page Visibility, 2011Draft Page Visibility 2, 2013

当CSS元素被遮挡时,它们似乎没有被优化掉,因此无法正确测量它们。我尝试了许多不同的属性导致回流(高度,宽度,框阴影等),并且无法从中获得任何有意义的指标。

requestAnimationFrame仅在更改选项卡且浏览器窗口变得模糊时才会限制动画,但不会处理折叠以下的内容。此外,由于raf仅附加在窗口级别,因此无法绑定到特定的dom节点(在其实现中似乎是短视的)。

参考:requestAnimationFrame

我还没有完成对WebGL的测试,但是这仅限于少数现代浏览器(对于旧版浏览器,闪存解决方案可接受的结果)。

我还没有完成对canvas的测试,但这可能是一个很好的解决方案,因为它得到了比WebGL更广泛的浏览器支持。

我甚至没有开始考虑嵌入式对象及其可以提供的内容。

我没有查看ActiveX控件以查看是否有任何可能有用的内容。

我没有看过HTML5视频。

动画GIF似乎只在Firefox中进行了优化。再次感谢,Mozilla!

因此,每个浏览器供应商如何优化页面呈现的神秘和魔力继续扼杀我的进步。然而,单独的元素位置不能仅依赖于元素实际上是否可见的真实指示,因为页面可能具有使框架内容模糊的其他层,或者内容可能以排除任何有意义的可见渲染的方式显示(例如更改内容的三维旋转以使其不可见。)

欢迎任何关于浏览器如何实际优化显示内容或其他方向或实际答案的头脑风暴。

同样,here is an older SO question也部分地包含了这个问题。

2 个答案:

答案 0 :(得分:2)

我在下面的代码中使用了Mozilla mozPaintCount,但是我没有得到我期望的FPS值。

第1部分:运行此代码一次以填充变量。

var currentFrames = window.mozPaintCount, currentTime = new Date();

第2部分:在第1部分之后的任何时间运行此代码。

(window.mozPaintCount - currentFrames)/((new Date() - currentTime)/1000)

结果显示FPS,对于我的网站,我得到9FPS。 Chrome FPS计数器显示我60FPS。

总体而言,浏览器的页面渲染性能是Web Dev World中一个相对较新的主题。除了Chrome DevTools之外,其他所有主要供应商似乎都对展示性能工具不感兴趣。由于对网页渲染性能的兴趣有限,因此大量数据也是如此。

开发人员关注的重要绩效理念是。 Scroll Performance,对Paint Time的CSS效果,你提到的GIF动画,当然还有requestAnimationFrame。 http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/

真的,在首先进入这个领域之前,我建议您花一点时间真正了解浏览器为了呈现您的页面和更新该页面所做的事情。 http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

我会为你添加更多链接,但我的SO代表太低了。

答案 1 :(得分:1)

关于你写的关于requestAnimationFrame的内容:

  

此外,由于raf仅附加在窗口级别,因此无法绑定到特定的dom节点

你可以(理论上)让代码在iframe中运行,因此window对象是整个元素,或者1px iframe可能是你内容上的一个点。

我通过查看mozPaintCount(正如你所说的和@ alexK85在他们的回答中建议的那样)在Firefox中工作,以查看CSS更改后是否有重新绘制(浏览器在CSS更改后不立即重新绘制iframe超出视口)。 但是,我还没有能够在其他浏览器中使用requestAnimationFrame做类似的事情,以确定在CSS更改后是否立即重新绘制了iframe。

有没有人对raf如何用于确定浏览器是否进行重新绘制有任何建议?