最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Which queue is associated with requestAnimationFrame? - Stack Overflow

programmeradmin0浏览0评论

Today I was asked this question on an interview. I couldn't answer this question and the interviewer said there was a special queue for requestAnimationFrame callbacks. But I can't find any information on this.

If rAF has it's own queue then why is this queue never mentioned anywhere? We only mention macro- and microtask queues when we talk about Event Loop?

Today I was asked this question on an interview. I couldn't answer this question and the interviewer said there was a special queue for requestAnimationFrame callbacks. But I can't find any information on this.

If rAF has it's own queue then why is this queue never mentioned anywhere? We only mention macro- and microtask queues when we talk about Event Loop?

Share Improve this question edited Aug 31, 2023 at 2:17 padaleiana 1,0741 gold badge17 silver badges24 bronze badges asked Aug 30, 2023 at 12:35 b3rryb3rry 751 silver badge9 bronze badges 3
  • @Bergi no it's not "one of them". Task queues have their place in the event loop where they get visited, rAF callbacks have another place entirely. They don't participate in the same system. Only one task gets executed per event loop iteration, rAF callbacks are all executed in the same iteration one after the other. Note also how one will deal with browser task (thus not necessarily involving JS), while the other one is ensured to only contain JS callbacks in its list. – Kaiido Commented Aug 31, 2023 at 4:09
  • @Kaiido Right, your answer explains this much better than I can in a ment. Afaics, there is no microtask checkpoint after the render callbacks? – Bergi Commented Aug 31, 2023 at 4:20
  • Yes there is one after each callback in html.spec.whatwg/multipage/… itself from webidl.spec.whatwg/#invoke-a-callback-function (step 14). Basically, every time after a bunch of JS is executed, if there is nothing on the callstack anymore, the checkpoint is visited. – Kaiido Commented Aug 31, 2023 at 4:25
Add a ment  | 

3 Answers 3

Reset to default 10

We only mention macro- and microtask queues when we talk about Event Loop?

First, there is no mention of "macro" task in the specs, only tasks and microtasks (and then callbacks, more on that later).

Then, almost every task source have their own task queues in modern browsers, though they currently don't have to. So there isn't just two queues, one that would be the microtask queue and another one for all the tasks, there are a lot of task queues (each MessagePort instance can have its own task queue). This allows to have various priority for each task source. So that UI events can get treated before network ones, for instance.

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", 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.


Note: Since 2024 the update the rendering steps of the Window's event loop has been revamped so that it's called from a task, using its own dedicated task source. Though this doesn't change much conceptually to what is described in this answer, since the whole step is part of the same task, and not just the run the animation frame callbacks sub-step. Also, the only way (I know of) to tell it's indeed in a task is the longtask timing API.


This is important that conceptually all these steps are not executed in a tasks, because this means that any task queued from these callbacks will not get executed before the next rendering, while still ensuring that a ResizeObserver callback scheduled from a resize event for instance, will be called before.

Animation frame callbacks are stored in an ordered map, called the map of animation frame callbacks. It's not a queue per-se, since we can "cancel" the callbacks through the cancelAnimationFrame() method. Also this allows getting all the keys at the beginning of the run the animation frame callbacks algorithm which itself allows to schedule new callbacks from such a callback to the next animation frame without blocking the event loop forever (if it were a queue, the algorithm would keep calling new callbacks endlessly, like it does in the microtask checkpoint).

But that much details is a bit pedantic and unless you're really into this kind of stuff you shouldn't need to know more than

  • most native events and Web API callbacks are queued in task queues, which get visited at the beginning of the event loop with a prioritization system,
  • all microtasks are executed every time after a callback has been invoked, in a way you can stuck the event loop if queuing microtasks from a microtask,
  • some render-related native events and animation frames are treated in their own place in the event loop.

Still, I believe it's good to understand that there is this special update the rendering step in the event loop, that is distinct from the other queued tasks in that it doesn't participate in the task prioritization system. I often read that it has an higher priority but IMO it's wrong to say that and given we'll soon have true control over some tasks prioritization, it will grow more important. It also helps understand when the styles recalc are performed and the relationship with (synchronous) DOM updates, and other stuff related to the rendering in a browser. But if you're not applying to a position that involves the details of browser rendering, maybe they just expected the (IMO pretty bad and) colloquial "in the render queue", as is being used e.g. in P.Roberts's Loupe.

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

requestAnimationFrame is specific to the Web API. The callback that is given as argument is collected in an ordered map, which the HTML Standard identifies as a map of animation frame callbacks. This map is associated with the HTML document (or the global scope in case of a dedicated web worker).

This map (which can be understood as a queue), gets processed after the current task has pleted, including the processing of the microtask queue. This map is consumed as part of the rendering phase of the event loop. The HTML Standard specifies as step 13 of the rendering process:

  1. For each fully active Document in docs, run the animation frame callbacks for that Document, passing in now as the timestamp.

So the short answer to "which queue" would be: the map of animation frame callbacks as specified in the HTML Standard.

requestAnimationFrame has its own queue separate from DOM events. The events are invoked during the rendering phase of the event loop.

The spec calls it the "animation frame request callback list" -- though I wouldn't expect anyone other than a browser developer to be able to recite that name in an interview situation! For most web developers, this is browser-internal detail that doesn't normally impact the day to day; I'm surprised this was used as an interview question (unless you're interviewing to work for a browser developer.)

Here's a duplicate (but unanswered) question which has some more links in ments you might find useful.

发布评论

评论列表(0)

  1. 暂无评论