为了继续 Firefox Quantum 对高性能引擎的投入,Firefox 61 版本 将通过一项我们称之为 *保留显示列表* 的优化来提升现代界面的响应能力。与 Quantum 的 Stylo 和 WebRender 功能类似,开发者不需要在其网站上进行任何更改即可享受这些改进带来的好处。
我在 1 月份的 Mozilla 图形团队博客上写过关于 这个功能 的文章,当时它首次在 Nightly 中实现。现在,它已准备好与 Firefox 61 一起发布。如果您已经熟悉保留显示列表以及此功能如何优化绘制性能,您可以跳过前面部分,直接阅读关于我们工作成果和未来计划的内容。
使用显示列表
显示列表构建是指我们收集一组要在屏幕上显示的高级项目(边框、背景、文本等等),然后根据 CSS 绘制规则对列表进行排序,以正确的从后到前的顺序显示。在此阶段,我们会确定页面哪些部分已在屏幕上可见。
目前,每当我们想要更新屏幕上的内容时,我们都会从头开始构建一个全新的显示列表,然后使用它在屏幕上绘制所有内容。这在简化方面非常棒:我们不必担心确定哪些部分发生了更改或消失了。不幸的是,这个过程可能需要很长时间。这始终是一个性能问题,但随着网站变得越来越复杂,越来越多的用户能够使用更高分辨率的显示器,这个问题变得更加突出。
解决方案是在绘制之间保留显示列表——我们只为自上次绘制以来发生更改的页面部分构建一个新的显示列表,然后将新列表合并到旧列表中,以获得更新后的列表。这增加了更多复杂性,因为我们需要确定要从旧列表中删除哪些项目,以及在何处插入新项目。好处是,在很多情况下,新列表的大小可能比完整列表小得多。这为提升感知性能和节省大量时间创造了机会。
动机
作为 Firefox Quantum 发布前的准备工作,我们在 Firefox 中添加了新的 遥测数据,以帮助我们衡量绘制性能,从而使我们能够更明智地决定将精力投入到哪里。其中一项衡量标准定义了“缓慢”绘制的最低阈值(16 毫秒),并在出现这种情况时记录了在各种绘制阶段花费的时间百分比。我们预计显示列表构建会占很大比例,但结果仍然让我们感到惊讶:平均而言,显示列表构建消耗了超过 40% 的总绘制时间,而这些工作通常与上一帧几乎相同。我们一直计划彻底改造显示列表的构建和管理方式,但有了这些新的数据,我们决定将其作为我们绘制团队的首要任务。
结果
一旦我们完成了所有工作,下一步就是看看我们对性能产生了多大的影响!我们在 Beta 60 周期的前半部分启用了该功能,并将启用和未启用该功能的结果进行了比较。
第一个也是最显著的变化:绘制所需的中位时间(整个管道,不仅仅是显示列表构建)下降了超过 33%!
从图表中可以看到,启用保留显示列表后,绘制所需的中位时间约为 3 毫秒。4 月 18 日禁用该功能后,绘制时间上升到 4.5 毫秒。这为浏览器腾出了更多时间来运行 JavaScript、进行布局和响应输入事件。
另一个重要的改进是缓慢绘制发生的频率。禁用保留显示列表后,我们大约 7.8% 的时间无法在 16 毫秒内完成。启用后,这一比例下降到 4.7%,减少了近 40%。我们可以看到,我们不仅让快速绘制变得更快,而且对缓慢绘制情况也产生了重大影响。
未来工作
如上所述,我们并不总能保留显示列表。我们花时间确定页面哪些部分发生了更改;当我们的分析表明页面的大部分都发生了更改时,我们仍然必须重新构建整个显示列表,而分析所花费的时间就是浪费的时间。我们一直在努力尽早检测这种情况,但我们不可能完全避免这种情况。我们还在积极努力减少准备工作所需的时间,以便充分利用部分更新的机会。
保留显示列表也不能帮助我们在加载网页时第一次绘制。第一次绘制始终必须从头开始构建整个列表,因此在未来,我们将探索让它在整个过程中更快的方法。
感谢所有为实现这一目标做出贡献的人,包括:Miko Mynttinen、Jet Villegas、Timothy Nikkel、Markus Stange、David Anderson、Ethan Lin 和 Jonathan Watt。
关于 Matt Woodrow
Gecko 图形和布局工程师。