Skip to content

Specify event loop integration / priority intent #67

@shaseley

Description

@shaseley

Forking this from here into its own issue.

Problem: The way scheduler task priorities are integrated into the event loop in the spec is underspecified. The original goal was to allow UAs maximum flexibility to integrate these into their schedulers, but the intent is not clear, which is bad for other implementors and compat.

Task Priorities in Blink

This section describes how Blink implements priority mappings, included for reference for how postTask() fits in. Typically, scheduled tasks run in priority order as follows:

Blink Priority Task/Source
Highest Input: Discrete input, e.g. clicks and typing (NOT User Interaction task source), and input blocking tasks (hit test IPC)
Rendering: The first frame after discrete input, some use cases on Android, e.g. main thread gestures and gesture start (touch start)
Very High Rendering: if we haven't rendering in > 100 ms (rendering starvation prevention). This includes rAF-aligned input.
Internal tasks, including find-in-page and IPC forwarding (postMessage)
High 'user-blocking' postTask() tasks
Normal The vast majority of task sources, including networking, timers, posted-message, user interaction, database, etc.
'user-visible' postTask() tasks
Rendering default state
Low 'background' postTask() tasks
Rendering: during compositor-driven scrolling (under experiment to remove)
Best Effort Idle callbacks (during idle periods), a couple internal task types

This is the current state, but there are quite a few inactive — and a few active — experiments I left out.

Notes:

  • Rendering is a special case. We treat rendering (including rAF, rAF-aligned input, paint, etc.) as its own task (compositor task queue), and its priority is very dynamic, fluctuating between low and highest
  • 'user-blocking' can starve other tasks, but not input or rendering
    • Discrete input is always selected first
    • Rendering, including rAF-aligned input, has a starvation prevention mechanism

Specifying Priority

The intention of postTask() priorities:

  1. 'user-blocking' tasks should generally be considered higher priority than other tasks -- especially other task scheduling methods, including setTimeout() and same-window postMessage() (which is used as a scheduling API). But they shouldn't indefinitely block input and rendering.
  2. 'user-visible' tasks should be ~= other ways of scheduling tasks
  3. 'background' should be lower, but can run outside of idle periods

A challenge is that UAs are currently free to choose rendering opportunities and schedule between task types as they see fit, and I don't want to create a total ordering of tasks and stifle UA experimentation. But we need to make clear the intention and consider providing stronger guarantees.

This is also a challenge for scheduler.yield(), where want stronger guarantees (see this section). I wrote there about maybe using a denylist approach, where the relative ordering vs. some tasks sources is specified, providing some guarantees. Doing that for both APIs would be simpler/cleaner, and maybe a good place to start? And it could be potentially augmented with notes about intent and guidance.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions