This directory contains the Main Thread Scheduling APIs (
Note: These APIs are experimental and the details are still in flux.
For the full API shape and general design, please refer to the (active) design doc.
postTask() API allows developers to schedule tasks with a native scheduler (
window.scheduler), at a specific priority. The API is based on prioritized task queues, which is a common scheduling paradigm.
The scheduler maintains a set of global task queues—one of each priority—which developers can interact with directly via
scheduler.getTaskQueue() or indirectly through
Tasks are created with
taskQueue.postTask(foo). Initially, tasks are in a “pending” state, and transition to “running”, “canceled”, or “completed” as illustrated in the following diagram:
Tasks can be posted with an optional delay, which has similar behavior to
Tasks can be moved between task queues with
DOMScheduler is per-document, and observes document lifecycle changes via
ContextLifecycleObserver. When the context is destroyed, the
DOMScheduler stops running tasks.
DOMScheduler's primary function is to maintain DOMTaskQueues. When the
DOMScheduler is created (when first accessed via
window.scheduler), it creates a set of global
DOMTaskQueues, one of each priority. Global here means document-global, meaning all document script can access these via
window.scheduler. This is opposed to custom task queues, which developers will be able to create via
new TaskQueue() (WIP).
DOMTaskQueue wraps a
WebSchedulingTaskQueue, which is the interface to the Blink scheduler.
WebSchedulingTaskQueue is created through the document's
FrameScheduler, and is created with a
WebSchedulingPriority. The latter is used by the Blink scheduler to determine the priority of the underlying base::sequence_manager::TaskQueue.
DOMTaskQueue owns the
WebSchedulingTaskQueue, and its lifetime is tied to that of the
Document associated with the
WebSchedulingTaskQueue exposes a
TaskRunner, which the
DOMTaskQueue uses to post tasks to the Blink scheduler.
DOMTask is a wrapper for a callback, its arguments, its return value (for
task.result), and a
TaskHandle, which allows the
DOMTask to be canceled with
The Blink scheduler handles the actual task scheduling. A
DOMTask's callback is scheduled to run by posting it a task to a
TaskRunner—just as all tasks in Blink are. The
TaskRunner is obtained through the
WebSchedulingTaskQueue, which is owned by the
DOMTaskQueue that the
DOMTask is posted to.
TODO(shaseley): Add a diagram for the relation between all the different task queues.
The API uses the Blink scheduler to run its tasks, and each
WebSchedulingPriority maps to a base::sequence_manager::TaskQueue::QueuePriority.
There is no intervention from the scheduling API to enforce a certain order—the order that tasks run is strictly determined by the Blink scheduler based on the
By default, the Blink scheduler has an anti-starvation mechanism that will occasionally prioritize lower priority tasks over higher priority tasks. This can be disabled with BlinkSchedulerDisableAntiStarvationForPriorities, which we are relying on to achieve a static ordering (highest to lowest priority) of tasks.
The API is modeled after setTimeout and setInterval with regards to detached documents. When a document is detached, any queued tasks will be prevented from running, and future calls to postTask through a cached DOMScheduler or DOMTaskQueue will be no-ops and return null.