1. Introduction
This allotment is non-normative.
Scheduling would perchance perchance be a extremely vital developer diagram for making improvements to web put
performance. Broadly speaking, there are two areas the build scheduling would perchance perchance be
impactful: user-percieved latency and responsiveness. Scheduling can toughen
user-perceived latency to the diploma that decrease priority work would perchance perchance be pushed off
in prefer of greater priority work that at as soon as impacts quality of experience.
As an instance, pushing off execution of definite 3P library scripts all the scheme by page
load can earnings the user by getting pixels to the mask mask quicker. The same
applies to prioritizing work related to sigh material inside the viewport. For
script working on the vital thread, lengthy tasks can negatively have an effect on each and each enter
and visual responsiveness by blocking enter and UI updates from working.
Breaking apart these tasks into smaller pieces and scheduling the chunks or job continuations is a proven skill that applications and framework builders
exercise to toughen responsiveness.
Userspace schedulers typically work by providing the formula to agenda tasks and
controlling when those tasks fabricate. Duties typically cling an related
priority, which in enormous allotment determines when the duty will bustle, in relation to
other tasks the scheduler controls. The scheduler typically operates by
executing tasks for some duration of time (a scheduler quantum) earlier than yielding
administration relief to the browser. The scheduler resumes by scheduling a continuation
job, e.g. a name to setTimeout()
or postMessage()
.
Whereas userspace schedulers cling been capable, the speak would perchance perchance simply be
improved with a centralized browser scheduler and greater scheduling primitives.
The priority machine of a scheduler extends simplest as a ways because the scheduler’s
reach. A kill consequence of this for userspace schedulers is that the UA in overall
has no data of userspace job priorities. The one exception is that if the
scheduler uses requestIdleCallback()
for some of its work, but this
is puny to the bottom priority work. The same holds if there are a pair of schedulers on the page, which is increasingly more overall. As an instance, an app would perchance perchance
be built with a framework that has a schedueler (e.g. React), attain some
scheduling by itself, and even embed a aim that has a scheduler (e.g. an
embedded scheme). The browser is the supreme coordination point since the browser
has world data, and the match loop is in payment for working tasks.
Prioritization aside, the hot primitives that userspace schedulers rely on
are now not supreme for contemporary exercise circumstances. setTimeout(0)
is the canonical formula to
agenda a non-delayed job, but there tend to be minimal extend values (e.g. for
nested tasks) that will consequence in unhappy performance ensuing from elevated latency. A successfully-acknowledged workaround is to
exercise postMessage()
or a MessageChannel
, but these APIs weren’t designed for scheduling, e.g. you
can not queue callbacks. requestIdleCallback()
would perchance perchance be superb for
some exercise circumstances, but this simplest applies to idle tasks and does now not yarn for
tasks whose priority can commerce, e.g. re-prioritizing off-mask mask sigh material in
response to user enter, indulge in scrolling.
This file introduces a brand unique interface for builders to agenda and administration
prioritized tasks. The Scheduler
interface exposes a postTask()
skill to agenda tasks, and the specification
defines a chain of TaskPriorities
that administration execution
enlighten. Moreover, a TaskController
and its related TaskSignal
would perchance perchance be dilapidated to abort scheduled tasks and administration their priorities.
2. Scheduling Duties
2.1. Job Priorities
This spec formalizes three priorities to make stronger scheduling tasks:
enum {
TaskPriority "user-blocking" ,"user-visible" ,"background" };
user-blocking
is the absolute top priority,
and is intended to be dilapidated for tasks that are blocking the user’s skill to
work in conjunction with the page, equivalent to rendering the core experience or responding to
user enter.
user-visible
is the second absolute top
priority, and is intended to be dilapidated for tasks that visible to the user but now not
necessarily blocking user actions, equivalent to rendering secondary parts of the
page. Here is the default priority.
background
is the bottom priority, and
is intended to be dilapidated for tasks that are now not time-serious, equivalent to background
log processing or initializing definite third party libraries.
Demonstrate: Duties scheduled by a given Scheduler
bustle in strict priority
enlighten, that skill the scheduler will all the time bustle “user-blocking
”
tasks earlier than “user-visible
” tasks, which in flip all the time bustle
earlier than “background
” tasks.
2.2. The Scheduler
Interface
dictionary {
SchedulerPostTaskOptions AbortSignal ;
signal TaskPriority ; [
priority EnforceRange ]unsigned lengthy lengthy =0; };
extend callback =
SchedulerPostTaskCallback any (); [Exposed =(Window ,Worker )]interface {
Scheduler Promise any >postTask (SchedulerPostTaskCallback ,
callback optional SchedulerPostTaskOptions ={}); };
choices
Demonstrate: The signal
likelihood would perchance perchance be both an AbortSignal
or a TaskSignal
, but is printed as an AbortSignal
since
it is a superclass of TaskSignal
. For circumstances the build the priority would perchance perchance
commerce, a TaskSignal
is required. Nonetheless for circumstances the build simplest cancellation is
wanted, an AbortSignal
would suffice, perchance making it more uncomplicated to
integrate the API into existing code that uses AbortSignals
.
consequence=scheduler .
postTask
( callback, choices )Returns a promise that is fulfilled with the return payment of callback,
or rejected with theAbortSignal
‘s abort reason if the
job is aborted. If callback throws an error all the scheme by execution, the promise
returned bypostTask()
will doubtless be rejected with that error.The job’s
priority
is definite by the combination of likelihood’spriority
andsignal
:- If likelihood’s
priority
is specified, then
thatTaskPriority
will doubtless be dilapidated to agenda the duty, and the duty’s
priority is immutable. - Otherwise, if likelihood’s
signal
is
specified and is aTaskSignal
object, then the duty’s priority is
definite by likelihood’ssignal
‘s priority. In this case the duty’s priority is dynamic,
and would perchance perchance be modified by callingcontroller.setPriority()
for the relatedTaskController
. - Otherwise, the duty’s priority defaults to “
user-visible
“.
If likelihood’s
signal
is specified, then thesignal
is dilapidated by theScheduler
to
resolve if the duty is aborted.If likelihood’s
extend
is specified and elevated
than 0, then the execution of the duty will doubtless be delayed for a minimal ofextend
milliseconds.- If likelihood’s
A Scheduler
object has an related static priority
job queue scheme, which is a scheme from TaskPriority
to scheduler
job queue. This scheme is initialized to a brand unique empty scheme.
A Scheduler
object has an related dynamic priority
job queue scheme, which is a scheme from TaskSignal
to scheduler
job queue. This scheme is initialized to a brand unique empty scheme.
A Scheduler
object has a numeric subsequent enqueue
enlighten which is initialized to 1.
Demonstrate: The subsequent enqueue enlighten is a strictly rising quantity that
is dilapidated to search out out job execution enlighten across scheduler job queues of the
identical TaskPriority
inside the comparable Scheduler
. A logically comparable
different would be to area the subsequent enqueue enlighten on the match loop, since the top possible necessities are that the volume be strictly
rising and now not be repeated inside a Scheduler
.
Would or now not it be more superb to easily exercise a timestamp right here?
The postTask(callback, choices)
skill steps are to return the cease consequence of scheduling a postTask job for this given callback and choices.
2.3. Definitions
A scheduler job is a job with an additional numeric enqueue enlighten item, before everything situation to 0.
A scheduler job t1 is older than scheduler job t2 if t1’s enqueue enlighten decrease than t2’s enqueue enlighten.
The following job sources are outlined as scheduler job sources,
and must simplest be dilapidated for scheduler tasks.
- The posted job job source
This job source is dilapidated for tasks scheduled by
postTask()
.
A scheduler job queue is a struct with the following items:
- priority
A
TaskPriority
.- tasks
A situation of scheduler tasks.
A scheduler job queue queue’s first runnable job is the vital scheduler job in queue’s tasks that is runnable.
2.4. Processing Model
2.4.1. Queueing and Casting off Scheduler Duties
2.4.2. Scheduling Duties
To agenda a postTask job for Scheduler
scheduler given a SchedulerPostTaskCallback
callback and SchedulerPostTaskOptions
choices, bustle the following steps:
Let consequence be a brand unique promise.
Let signal be choices[“
signal
“] if choices[“signal
“] exists, or
otherwise null.If signal is now not null and it is aborted, then reject consequence with signal’s abort reason and return consequence.
Let priority be choices[“
priority
“] if choices[“priority
“] exists, or
otherwise null.Let queue be the cease consequence of selecting the scheduler job queue for scheduler given signal and priority.
Let extend be choices[“
delay
“].If extend is elevated than 0, then bustle steps after a timeout given scheduler’s related world object, “
scheduler-postTask
“, extend, and the following steps:Schedule a role to invoke a callback for scheduler given queue, signal, callback, and consequence.
Otherwise, agenda a role to invoke a callback for scheduler given queue, signal, callback, and consequence.
Return consequence.
Flee steps after a timeout doesn’t necessarily yarn for suspension;
locate whatwg/html#5925.
To agenda a role to invoke a callback for Scheduler
scheduler given a scheduler job queue queue, an AbortSignal
or
null signal, a SchedulerPostTaskCallback callback, and a promise consequence:
Let world be the related world object for scheduler.
Let file be world’s related
Doc
if world is aWindow
object; otherwise null.Let enqueue enlighten be scheduler’s subsequent enqueue enlighten.
Increment scheduler’s subsequent enqueue enlighten by 1.
Let job be the cease consequence of queuing a scheduler job on queue given enqueue enlighten, the posted job job source, and file, and that
performs the following steps:If signal is now not null, then add the following abort
steps to it:Fetch away job from queue.
Reject consequence with signal’s abort reason.
Because this algorithm would perchance perchance be known as from in parallel steps, parts
of this and other algorithms are keen. Namely, the subsequent enqueue enlighten would perchance perchance simply soundless be updated atomically, and accessing
the scheduler job queues would perchance perchance simply soundless happen atomically. The latter furthermore impacts
the match loop job queues (locate this field).
2.4.3. Deciding on the Subsequent Job to Flee
2.5. Examples
TODO(shaseley): Add examples.
3. Controlling Duties
Duties scheduled by the Scheduler
interface would perchance perchance be managed with a TaskController
by passing the TaskSignal
supplied by controller.signal
because the likelihood
when calling postTask()
.
The TaskController
interface supports aborting and changing the priority of
a role or crew of tasks.
3.1. The TaskPriorityChangeEvent
Interface
[Exposed =(Window ,Worker )]interface :
TaskPriorityChangeEvent Occasion {(
constructor DOMString ,
form TaskPriorityChangeEventInit );
priorityChangeEventInitDict readonly attribute TaskPriority previousPriority ; };dictionary :
TaskPriorityChangeEventInit EventInit {required TaskPriority ; };
previousPriority
match .
previousPriority
Returns the
TaskPriority
of the correspondingTaskSignal
sooner than
thisprioritychange
match.The unique
TaskPriority
would perchance perchance be read withmatch.aim.priority
.
The previousPriority
getter
steps are to return the payment that the corresponding attribute modified into as soon as initialized
to.
3.2. The TaskController
Interface
dictionary {
TaskControllerInit TaskPriority ="user-visible"; }; [
priority Exposed =(Window ,Worker )]interface :
TaskController AbortController {constructor (optional TaskControllerInit ={});
init undefined setPriority (TaskPriority ); };
priority
Demonstrate: TaskController
‘s signal
getter, which is
inherited from AbortController
, returns a TaskSignal
object.
controller=unique
TaskController
( init )Returns a brand unique
TaskController
whosesignal
is
situation to a newly createdTaskSignal
with itspriority
initialized to init’spriority
.controller .
setPriority
( priority )Invoking this suggests will commerce the related
TaskSignal
‘s priority, signal the priority commerce to any observers, and
situation offprioritychange
occasions to be dispatched.
The setPriority(priority)
skill steps are to signal priority commerce on this‘s signal given priority.
3.3. The TaskSignal
Interface
[Exposed =(Window ,Worker )]interface :
TaskSignal AbortSignal {readonly attribute TaskPriority priority ;attribute EventHandler onprioritychange ; };
Demonstrate: TaskSignal
inherits from AbortSignal
and would perchance perchance be dilapidated in APIs that
acquire an AbortSignal
. Moreover, postTask()
accepts an AbortSignal
, that will doubtless be vital if dynamic prioritization is now not wanted.
signal .
priority
Returns the
TaskPriority
of the signal.
A TaskSignal
object has an related TaskPriority
priority.
A TaskSignal
object has an related priority changing boolean, intially situation to pretend.
A TaskSignal
object has related priority commerce algorithms,
which is a situation of algorithms, initialized to a brand unique empty situation. These
algorithms are to be executed when its priority changing payment
is real.
The priority
getter steps are to return this‘s priority.
The onprioritychange
attribute
is an match handler IDL attribute for the onprioritychange
match handler, whose match handler match form is prioritychange
.
To add a priority commerce algorithm algorithm to a TaskSignal
object signal, append algorithm to signal’s priority commerce algorithms.
3.4. Examples
TODO(shaseley): Add examples.
4. Changes to Diversified Standards
4.1. The HTML Normal
4.1.1. WindowOrWorkerGlobalScope
Each and each object implementing the WindowOrWorkerGlobalScope
mixin has a
corresponding scheduler, which
is initialized as a brand unique Scheduler
.
partial interface mixin WindowOrWorkerGlobalScope { [Replaceable ]readonly attribute Scheduler scheduler ; };
The scheduler
attribute’s
getter steps are to return this‘s scheduler.
4.1.2. Occasion loop: definitions
Change: For each and each match loop, every job source would perchance perchance simply soundless be related to
a divulge job queue.
With: For each and each match loop, every job source that is now not a scheduler job source would perchance perchance simply soundless be related to a divulge job queue.
4.1.3. Occasion loop: processing mannequin
Add the following steps to the match loop processing steps, earlier than step 1:
Let queues be the situation of the match loop‘s job queues that
maintain now not decrease than one runnable job.Let schedulers be the situation of all
Scheduler
objects whose related agent’s match loop is that this match loop and that cling a runnable job.If schedulers and queues are each and each empty, skip to the
microtasks
step below.
Modify step 1 to read:
Let taskQueue be undoubtedly one of many following, chosen in an implementation-outlined formula:
If queues is now not empty, undoubtedly one of many job queues in queues,
chosen in an implementation-outlined formula.If schedulers is now not empty, the cease consequence of selecting the duty queue of the following scheduler job from undoubtedly one of many
Scheduler
s in schedulers, chosen in an implementation-outlined formula.
The taskQueue on this step will both be a situation of tasks or a situation of scheduler tasks. The steps that modify to simplest elevate away an item, in speak that they’re roughly successfully matched. Ideally, there would be a
overall job queue interface that supports a pop()
skill that would perchance perchance return a
undeniable job, but that would perchance perchance invlove an even quantity of refactoring.
5. Security Concerns
This allotment is non-normative.
The vital security consideration for the APIs outlined on this specification is
whether or now not any data is perchance leaked between origins by
timing-basically basically based facet-channel assaults.
5.1. postTask
as a High-Resolution Timing Source
This API can not be dilapidated as a excessive-resolution timing source. Esteem setTimeout()
‘s timeout payment, postTask()
‘s extend
is expressed in
entire milliseconds (the minimal non-zero extend being 1 ms), so callers can not
divulge any timing more proper than 1 ms. Additional, since tasks are queued when
their extend expires and now not bustle straight, the precision accessible to callers
is extra reduced.
5.2. Monitoring One other Origin’s Duties
The second consideration is whether postTask()
leaks any
facts about other origins’ tasks. We elevate into consideration an attacker working on one
starting up looking out to operate facts about code executing in a single other starting up (and
therefore in a separate match loop) that is scheduled within the comparable thread in a
browser.
Because a thread inside a UA can simplest bustle tasks from one match loop at a time,
an attacker would perchance perchance simply secure a scheme to manufacture facts about tasks working in a single other
match loop by monitoring when their tasks bustle. As an instance, an attacker would perchance perchance
flood the machine with tasks and demand them to bustle consecutively; if there are
enormous gaps in between, then the attacker would perchance perchance infer that one other job ran,
perchance in a special match loop. The working out uncovered in such a case
would rely on implementation dinky print, and implementations can minimize the
quantity of data as described below.
What Files May well perchance Be Won?
Concretely, an attacker would secure a scheme to detect when other tasks are executed
by the browser by both flooding the machine with tasks or by recursively
scheduling tasks. Here is a acknowledged attack that would perchance perchance be executed with existing APIs indulge in postMessage()
. The tasks that bustle quite than the attacker’s would perchance perchance be
tasks in other match loops as successfully as other tasks within the attacker’s match loop,
in conjunction with inside UA tasks (e.g. garbage sequence).
Assuming the attacker can resolve with a excessive diploma of likelihood that the
job executing is in a single other match loop, then the request becomes what
extra data can the attacker learn? Since inter-match-loop job
choice is now not specified, this data will doubtless be implementation-dependent
and depends on how U.s.a.enlighten tasks between match loops. Nonetheless U.s.a.that exercise a
prioritization procedure that treats match loops sharing a thread as a single
match loop are inclined to exposing more data.
It is vital to deem the situation of doable tasks that a UA would perchance perchance
elevate quite than the attacker’s, which corresponds to the straightforward job received.
When an attacker floods the machine with tasks, the placement of that chances are high you’ll perchance agree with tasks would
be the rest the UA deems to be greater priority at that second. This would perchance perchance be
the cease consequence of a static prioritization procedure, e.g. enter is all the time absolute top
priority, network is second absolute top, and so forth., or this is also more dynamic, e.g.
the UA typically chooses to bustle tasks from other job sources relying on
how lengthy they’ve been starved. The utilization of a dynamic procedure increases the placement of doable
job which in flip decreases the fidelity of the straightforward job.
postTask()
supports prioritization for tasks scheduled with it.
How these tasks are interleaved with other job sources is furthermore
implementation-dependent, but it completely would perchance perchance simply be that chances are high you’ll perchance agree with for an attacker to
extra minimize the placement of doable tasks that can bustle quite than its have by
leveraging this priority. As an instance, if a UA uses a straightforward static
prioritization procedure spanning all match loops in a thread, then the utilization of user-blocking
postTask()
tasks quite than postMessage()
tasks would perchance perchance decrease
this situation, relying on their relative prioritization and what’s between.
What Mitigations are Doable?
There are mitigations that implementers can elevate into consideration to slit back the wretchedness:
The build that chances are high you’ll perchance agree with, isolate cross-starting up match loops by working them in different
threads. This type of attack depends on the match loops sharing a thread.Use an inter-match-loop scheduling protection that is now not strictly in accordance to
priority. As an instance, an implementation would perchance perchance exercise spherical-robin or
honest-scheduling between match loops to cease leaking facts about
job priority. One other likelihood is to execute definite decrease priority tasks are
periodically cycled in to cease inferring priority data.
6. Privateness Concerns
This allotment is non-normative.
Now we cling evaluated the APIs outlined on this specification from a privacy
perspective and attain now not agree with there to be any privacy concerns.
Conformance
Doc conventions
Conformance necessities are expressed
with a combination of descriptive assertions
and RFC 2119 terminology.
The vital words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”
within the normative parts of this file
are to be interpreted as described in RFC 2119.
Nonetheless, for readability,
these words attain now not seem in all uppercase letters on this specification.
All of the textual sigh material of this specification is normative
except for sections explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples on this specification are introduced with the words “as an illustration”
or are situation except for the normative textual sigh material
with class="instance"
,
indulge in this:
Here is an instance of an informative instance.
Informative notes begin with the note “Demonstrate”
and are situation except for the normative textual sigh material
with class="repeat"
,
indulge in this:
Demonstrate, right here is an informative repeat.
Conformant Algorithms
Necessities phrased within the imperative as allotment of algorithms
(equivalent to “strip any main area characters”
or “return pretend and abort these steps”)
are to be interpreted with the that skill of the principle note
(“must”, “would perchance perchance simply soundless”, “would perchance perchance simply”, and so forth)
dilapidated in introducing the algorithm.
Conformance necessities phrased as algorithms or divulge steps
would perchance perchance be implemented in any formula,
so lengthy because the cease consequence’s comparable.
In divulge, the algorithms outlined on this specification
are supposed to be straightforward to label
and are now not supposed to be performant.
Implementers are impressed to optimize.