prioritization.md (9225B)
Firefox Network Scheduling and Prioritization
Please note that this document is a first draft and is subject to further refinement and updates. Refers to Fx 132+
Scheduling
Firefox employs several techniques to orchestrate network request scheduling:
DOM Preload Scanner (Speculative Loader)
- Runs on a background thread, scanning HTML for resource URLs to preload.
- Adds discovered resources to a speculative load queue.
- See MDN Documentation on HTML Parser Threading (archived).
DOM Parser (Non-Speculative)
- Makes requests for elements as the DOM tree is constructed.
Class of Service
- Categorizes requests based on context or request target. See nsIClassOfService.idl
- Categories (e.g. Leader, Normal, Follower, Speculative, etc) can affect both network and cache behaviours
- May defer scheduling of certain requests (e.g., trackers classified as
ClassOfService::Tail). For detailed information about resource tailing, see Firefox Resource Tailing Documentation. - Also defines base urgency for a request
Priority
As HTTP/1.1 does not feature a prioritization system (sequential requests), Firefox uses supportsPriority and classOfService to order requests.
With HTTP/2 and HTTP/3 utilizing a single, multiplexed connection to each host, request priority becomes crucial due to bandwidth limitations. Priority is expressed using the Extensible Prioritization Scheme, which includes:
- Urgency: Ranges from
0(highest priority) to7(lowest priority). Resources with a lower numerical urgency are delivered before those with higher urgencies. For example, all resources with urgency2are transferred before those with urgency3begin. - Incremental: A boolean indicating whether bandwidth should be split between this resource and others of the same urgency. The incremental flag determines if resources of the same urgency are sent sequentially (
inot present) or incrementally (i).
These priorities are calculated based on the following factors:
- Resource type and its placement within the document or viewport.
- Assigned Class of Service
- Use of the SupportsPriority interface.
- Application of PriorityHints (e.g.,
fetchpriority="high") adjustments which is implemented viaSupportsPriority - Backgrounded tabs will have their priorities lowered.
Resource Scheduling and Priority Table
| Resource Type | Class of Service | supportsPriority | Urgency | Incremental | Notes |
|--------------------------------------|------------------------------------------|--------------------------------------------------------------------------------------|-----------------------------------------------|-----------------|---------------------------------------------------------------------------|
| HTML, Root Document | UrgentStart (64) | PRIORITY_HIGHEST, -20 | 0 | true | |
| CSS (`<head>`, Render-Blocking) | Leader (1) | PRIORITY_NORMAL, 0<br>fetchpriority=high: PRIORITY_HIGH, -20<br>fetchpriority=low: PRIORITY_LOW, 0 | 2 <br>fetchpriority=high: 0<br>fetchpriority=low: 2 | false | |
| CSS (rel=preload) | Leader (1) | PRIORITY_HIGHEST, -20<br>fetchpriority=high: PRIORITY_HIGH, -20<br>fetchpriority=low: PRIORITY_LOW, -10| 0 <br>fetchpriority=high: 0<br>fetchpriority=low: 1 | false | |
| CSS (Body) | Leader (1) | PRIORITY_NORMAL, 0 <br>fetchpriority=high: PRIORITY_HIGH, -20<br>fetchpriority=low: PRIORITY_NORMAL, 0 | 2 <br>fetchpriority=high: 0<br>fetchpriority=low: 2| false | |
| JavaScript (Blocking) | Leader (1) | PRIORITY_NORMAL, 0 <br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOW, 10 | 2 <br>fetchpriority=high: 1<br>fetchpriority=low: 3 | false | |
| JavaScript (rel=preload) | Unblocked (16) | PRIORITY_HIGHEST, -20 <br>fetchpriority=high: PRIORITY_HIGH, -20<br>fetchpriority=low: PRIORITY_LOW, 10| 1 <br>fetchpriority=high: 1<br>fetchpriority=low: 4 | false | |
| JavaScript (Async) | TailAllowed (512), Unblocked (16) | PRIORITY_NORMAL, 0 <br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOW, 10 | 3<br>fetchpriority=high: 2<br>fetchpriority=low: 4 | false | |
| JavaScript (Defer) | Unblocked (16) | PRIORITY_NORMAL, 0 <br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOW, 10 | 3<br>fetchpriority=high: 2<br>fetchpriority=low: 4 | false | |
| Font @font-face | TailForbidden (1024) | PRIORITY_HIGH, -10 | 3 | false | Urgency affected by TailForbidden CoS. fetchpriority applied via rel="preload" |
| Font (rel=preload) | TailForbidden (1024), Unblocked (16) | PRIORITY_HIGH, -10<br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOW, 10 | 2<br>fetchpriority=high: 2<br>fetchpriority=low: 4 | false | |
| Image | (0) | PRIORITY_LOW, 10<br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOWEST, 20 | 5<br>fetchpriority=high: 3<br>fetchpriority=low: 6 | true | |
| Image (rel=preload) | (0) | PRIORITY_LOW, 10<br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOWEST, 20 | 4<br>fetchpriority=high: 3<br>fetchpriority=low: 5 | true | |
| Image (About to Be Rendered) | (0) | PRIORITY_HIGH, -10 | 3 | true | See: image_layout_network_priority and bug 1915817 |
| Fetch | (0) | PRIORITY_NORMAL, 0<br>fetchpriority=high: PRIORITY_HIGH, -10<br>fetchpriority=low: PRIORITY_LOW, 10 | 4<br>fetchpriority=high: 3<br>fetchpriority=low: 5 | false | |
| Tracker (Script) | Tail (256), Unblocked (16) | PRIORITY_NORMAL, 0 | 3 | false | Request is tailed, i.e., deferred by a constant multiplied by the number of pending requests. |