docs

Explainer: queueMicrotask

Motivation

There are several existing ways to queue a microtask (introduction to microtasks):

The library asap uses these tricks to provide a cross-browser way of queueing a microtask.

Developers and frameworks are already using these methods to queue microtasks. The platform should support queueing microtasks directly as a primitive operation.

Reasons to expose this API directly

Proposal

This proposal would add an API to directly queue a microtask without the need for any tricks. E.g.

queueMicrotask(callback);

This API would be available to JS in web pages via Window and to JS in workers via WorkerGlobalScope.

Usage

Microtasks are useful when you need async ordering behaviour, but want the work done as soon as possible. Beware that doing large amounts of work in microtasks is just as bad for jank and interactivity as doing that work in-place in your JS. Depending on the desired effect, setTimeout(someFunction, 0) or requestAnimationFrame(someFunction) may be the correct choice.

Example

function microtask() {
  console.log("microtask");
}

function task() {
  console.log("task");
}

setTimeout(task, 0);
queueMicrotask(microtask);

Will result in the following order of operations

  1. Log “microtask”
  2. Return to the event loop and allow rendering/input callbacks to occur if appropriate
  3. Log “task”

Risks

Infinite loops of microtasks

A microtask posted with queueMicrotask may itself post another microtask so of course buggy websites can create infinite loops using this API. Since these are microtasks, the current task will never complete, the page will be unresponsive and the slow script dialog will be triggered. This is different to infinite chains of setTimout calls which silently consume 100% CPU but are easier to let slip into production since the tasks complete and event handling continues as normal.

No new mitigations are proposed to handle this risk, the impact of the bug is immediately visible and the slow script dialog seems adequate.