哪个队列与 requestAnimationFrame 关联?

2024-04-12

今天我在接受采访时被问到这个问题。我无法回答这个问题,面试官说有一个特殊的队列用于 requestAnimationFrame 回调。但我找不到任何这方面的信息。

如果 rAF 有它自己的队列,那么为什么这个队列从未在任何地方被提及?当我们谈论事件循环时,我们只提到宏任务队列和微任务队列?


当我们谈论事件循环时,我们只提到宏任务队列和微任务队列?

首先,规范中没有提到“宏观”任务,只是tasks https://html.spec.whatwg.org/multipage/webappapis.html#concept-task and 微任务 https://html.spec.whatwg.org/multipage/webappapis.html#microtask(进而回调 https://webidl.spec.whatwg.org/#idl-callback-interfaces,稍后会详细介绍)。

然后,几乎每一个任务源 https://html.spec.whatwg.org/multipage/webappapis.html#task-source有自己的任务队列 https://html.spec.whatwg.org/multipage/webappapis.html#task-queue在现代浏览器中,尽管目前还没有have到。所以不只是两个队列,一个是微任务队列 https://html.spec.whatwg.org/multipage/webappapis.html#microtask-queue另一个为所有tasks, 有很多的任务队列 (each MessagePort实例可以有自己的任务队列)。这允许每个人有不同的优先级任务源。例如,用户界面事件可以在网络事件之前得到处理。

But requestAnimationFrame callbacks are not even queued in a task queue. This method schedules a callback that (in the specs1) isn't invoked from a task, but from a special place in the event loop called "update the rendering" https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering, itself visited only once in a while (generally when the monitor sends a VSync signal and the document is active), which will also fire scroll and resize events, Web Animation updates, ResizeObserver callbacks, etc. and the rendering of the page.

重要的是,从概念上讲,所有这些步骤都是not执行于tasks,因为这意味着任何task从这些回调中排队的函数不会在下一次渲染之前执行,同时仍然确保ResizeObserver回调安排从resize例如事件,将在之前调用。

动画帧回调存储在一个有序地图 https://infra.spec.whatwg.org/#ordered-map,称为动画帧回调图 https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#list-of-animation-frame-callbacks。这不是一个queue本身,因为我们可以通过“取消”回调cancelAnimationFrame()方法。这也允许获取开头的所有键运行动画帧回调 https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#run-the-animation-frame-callbacks算法本身允许从这样的回调安排新的回调到下一个动画帧,而不会永远阻塞事件循环(如果它是一个队列,算法将不断地调用新的回调,就像在微任务检查点中一样)。

但这么多细节有点迂腐,除非你真的喜欢这种东西,否则你不需要知道更多

  • 大多数本机事件和 Web API 回调都在任务队列中排队,这些任务队列在事件循环开始时通过优先级系统进行访问,
  • 每次调用回调后都会执行所有微任务,如果从微任务中排队微任务,您可能会陷入事件循环,
  • 一些与渲染相关的本机事件和动画帧在事件循环中自己的位置进行处理。

尽管如此,我相信了解这种特殊的情况还是有好处的更新渲染图事件循环中的步骤,它与其他排队任务不同,因为它不参与任务优先级系统。我经常读到它具有更高的优先级,但在我看来,这样说是错误的,并且考虑到我们很快就会有 https://wicg.github.io/scheduling-apis/真正控制一些任务的优先级,它会变得更加重要。它还有助于理解何时执行样式重新计算以及与(同步)DOM 更新的关系,以及与浏览器中渲染相关的其他内容。但是,如果您不申请涉及浏览器渲染细节的职位,也许他们只是期望(IMO 非常糟糕)口语“在渲染队列中”,就像正在使用的那样。在P·罗伯茨的放大镜 http://latentflip.com/loupe/.

1: Firefox, for one, actually queues tasks even for these, but they do it in a way it's not observable.

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

哪个队列与 requestAnimationFrame 关联? 的相关文章