使用 APZ 在 Firefox 46 中实现更流畅的滚动

您是否曾经在 Facebook 或 Twitter 上愉快地向下滚动页面,突然浏览器似乎卡住了?它会卡在那里好几秒钟,您不确定它是否会崩溃。然后,终于,页面突然跳动以追赶您的滚动,让您感到迷茫?这就是所谓的卡顿,在 Firefox 46 Beta 版中,我们正在努力使卡顿成为过去。

在 Firefox 46 Beta 版中,我们正在为 Firefox 引入异步平移和缩放 (APZ)。这项底层技术最初是为我们的移动平台开发的,在移动平台上,对触摸输入的响应能力是性能支柱之一。现在,我们将它移植到我们的桌面平台,并将其用于鼠标滚轮/触控板滚动。使用 APZ,即使页面正在运行大量 JavaScript 或重绘速度很慢,向下滚动页面也应该流畅且无卡顿。在未来的版本中,我们计划将 APZ 扩展到其他滚动方法(例如触控和滚动条拖动)。

幕后

浏览器传统上在浏览器的主要事件处理线程上处理用户输入事件。这意味着它可能会被浏览器正在执行的任何其他操作阻塞,包括运行脚本和绘制。在 Firefox 中,电解 (e10s) 项目将内容进程与主浏览器进程分离。这为我们提供了另一种处理输入事件的路径。与以往将输入事件从父进程传递到内容进程以驱动滚动不同,输入事件用于在父进程合成器中驱动滚动,然后才转发到子进程以进行正常处理和分派。下图说明了这一点。

noapz

图 1. 无 e10s 或 APZ 的代码流程。

 

在上面的图 1 中,潜在的长时间运行操作用红色表示。虽然合成器线程仍然可以快速合成到屏幕上(每秒 60 帧),但它依赖于从主线程获取绘制内容。由于主线程可能会被长时间运行的 JavaScript 或绘制操作阻塞,因此来自滚动输入的绘制更新也会被阻塞,无法到达合成器。

apz

图 2. 有 e10s 和 APZ 的代码流程

在上面的图 2 中,我们可以看到引入 e10s 和 APZ 如何影响流程。输入事件到达父进程的主线程,该线程没有长时间运行的操作。因此,它可以快速将输入事件传递到合成器线程,APZ 代码在其中使用它进行异步滚动。同时,输入事件也被转发到子进程的主线程,在那里它被传递到网页内容并触发重绘。即使这些操作可能仍然很慢,它们也不会再阻止滚动更新合成到屏幕上。

这种方法虽然对响应能力很有帮助,但需要启用 e10s,并且还会引入一定程度的复杂性。例如,父进程需要能够对子进程进行一定程度的命中测试,以了解输入事件落在哪里。它还意味着父进程需要一种机制来处理网页调用了preventDefault() 的事件。有关所有这些工作原理的详细信息,请参阅APZ 文档

棋盘格

当然,没有什么是免费的,APZ 也需要付出代价。APZ 确实消除了卡顿,但在某些情况下,它是通过棋盘格来实现的。棋盘格是指您滚动速度超过浏览器绘制页面的速度时会出现的情况。当这种情况发生时,您新滚动位置的内容还没有被绘制出来,因此我们只显示一个纯色背景。(术语棋盘格来自最初的 iPhone 实现,它会显示棋盘格图案。)一旦绘制赶上来,内容就会填充进去。

由于内存限制,异步滚动不可避免地会出现棋盘格现象;这是消除卡顿的代价。但是,在大多数情况下,它应该不明显 - 它只持续几百毫秒,我们正在努力进一步缩短这个时间。我们通过提前绘制可见区域之外的内容来做到这一点,这样当用户滚动时,内容就可以立即显示。通过更好地预测用户将要滚动的位置,我们可以减少棋盘格的显示数量。总的来说,用棋盘格来换取卡顿可以带来更好的用户体验,因为浏览器本身保持响应,不会出现卡住或挂起。

与滚动相关的效果

APZ 还会影响与滚动相关的效果的工作方式。由于 APZ 与主线程异步地进行滚动,这必然意味着网页内容看到的滚动事件将会延迟。换句话说,从用户滚动到滚动事件可以分派到网页内容之间存在一定的传播延迟。如果页面使用滚动事件在页面上重新定位一些内容,则处理该更改并将其显示给用户将需要额外的时间。这意味着与滚动相关的效果可能看起来延迟且与滚动不同步。在理想情况下,用户滚动和与滚动相关的效果可见之间的延迟不应超过 2 帧(在每秒 60 帧的帧速率下为 33 毫秒)。虽然这几乎不明显,但实际上如果页面使用脚本占用了主线程,或者页面很复杂,需要一段时间才能重绘,则可能需要更长的时间。因此,页面仍然需要尽可能保持响应,方法是将长时间运行的脚本分解或使用 worker。

为了完全消除这种延迟,作者可以选择使用 CSS 定位而不是 JavaScript 来实现与滚动相关的效果。我们为最常用的与滚动相关的效果提供了 CSS 选项,包括粘性定位和视差效果。使用 CSS 定位,我们可以提前知道定位将如何变化,因此我们可以使其与用户的滚动完全同步。您可以在 MDN 文章中找到有关与滚动相关的效果的示例和更多详细信息。

关于 Kartikaya Gupta

Kartikaya Gupta 是 Mozilla 平台图形团队的开发人员,负责 Gecko 渲染引擎中的滚动相关事项。

Kartikaya Gupta 的更多文章…


15 条评论

  1. abral

    这意味着 e10s 将在 Firefox 46 中启用吗?

    2016 年 2 月 9 日 下午 10:11

  2. Luca

    我个人发现 Windows 8 中的 IE10 和 IE11 在滚动页面时非常流畅和快速,而且没有出现 Firefox 3 年前出现的延迟和卡顿。

    我不知道问题是否相同,但我希望这能让 Firefox 在速度方面与 IE 渲染“抗衡”。

    2016 年 2 月 10 日 上午 00:48

  3. nicofrand

    “我们为最常用的与滚动相关的效果提供了 CSS 选项,包括粘性定位和视差效果。”

    最常用,我不确定,我们很多人仍在等待使用表格标题的粘性定位 :/。

    2016 年 2 月 10 日 上午 01:39

  4. Kartikaya Gupta

    当前计划是在 Firefox 46 中启用 e10s,但并非一定对所有用户启用。我们可能会将其对已知配置不佳的用户禁用。APZ 只有在启用 e10s 的用户身上才会启用。

    2016 年 2 月 10 日 上午 06:05

  5. Jason Weathersby

    Abral,
    发布功能取决于质量,而不是由特定版本设置,因此在我们对该功能已准备好进行普遍发布感到满意之前,我们无法承诺具体版本。

    2016 年 2 月 10 日 下午 12:11

  6. abral

    Jason,我之所以这样问,是因为文章标题说的是“在 Firefox 46 中”。感谢您澄清。

    2016 年 2 月 10 日 下午 13:00

    1. Jason Weathersby

      Abral

      抱歉造成混淆。我们本来可以更清楚一点。

      2016 年 2 月 11 日 上午 09:29

  7. Peter J. Sloetjes

    在当前的 Nightly 版本中,我在深色背景页面快速滚动时遇到白色闪烁的问题。填充颜色是如何确定的?如果填充颜色不能保证与顶部元素的计算样式相同,那么如果可以通过用户偏好设置它,将会很好。

    2016 年 2 月 13 日 下午 3:18

  8. Pete

    您好,您是否在新的 Retina/5k iMac 上体验过滚动?它在 25-35 fps 之间 :-( 即使在 v. 47 版本中,Chrome/Safari 也没有任何问题。

    2016 年 2 月 14 日 上午 10:36

  9. Kartikaya Gupta

    Peter,我们确实尝试使用滚动帧的背景颜色。滚动帧上可能存在一些元素,这些元素会导致背景颜色看起来像是其他的颜色。当图像用作背景时,这种情况尤其明显。话虽如此,如果您遇到一个您认为处理不当的特定案例,请为其提交一个 bug 报告,我们会进行调查。谢谢!

    2016 年 2 月 15 日 下午 8:04

  10. Kartikaya Gupta

    Pete,不,我个人没有尝试在 5k iMac 上滚动。可能是我们需要调整一些高分辨率显示器的设置来提高性能。如果您能为此提交一个 bug 报告并包含一个演示问题的特定 URL,将会很有帮助。谢谢!

    2016 年 2 月 15 日 下午 8:06

  11. Pete

    尊敬的 Kartikaya,感谢您的回复。我会在 bugzilla 上这样做。

    我使用非 Retina 27 以及新的 Retina iMac(配备第二好的 GPU - AMD m395),非 Retina 上的网站大多在 50-60 fps 之间,但 Retina iMac 上通常低 20 fps :-(

    2016 年 2 月 16 日 上午 0:20

  12. Peter J. Sloetjes

    您好 Kartikaya,感谢您的回复。今天我查看了我提到的问题,但它似乎不再在我之前注意到的页面上出现:)。我的印象是,Firefox 中的滚动现在比以往任何时候都更加流畅,因此 APZ 似乎非常有效。谢谢!

    2016 年 2 月 16 日 下午 1:45

  13. rafuse

    感谢您!!真的,我已经等这个很久了!

    2016 年 2 月 21 日 上午 5:11

  14. Wellington Torrejais da Silva

    非常好!

    2016 年 2 月 24 日 下午 3:11

本文的评论已关闭。