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.
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
).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 urgency2
are transferred before those with urgency3
begin.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 (
i
not 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 |
2 |
false |
|
CSS (rel=preload) | Leader (1) |
PRIORITY_HIGHEST, -20 |
0 |
false |
|
CSS (Body) | Leader (1) |
PRIORITY_NORMAL, 0 |
2 |
false |
|
JavaScript (Blocking) | Leader (1) |
PRIORITY_NORMAL, 0 |
2 |
false |
|
JavaScript (rel=preload) | Unblocked (16) |
PRIORITY_HIGHEST, -20 |
1 |
false |
|
JavaScript (Async) | TailAllowed (512), Unblocked (16) |
PRIORITY_NORMAL, 0 |
3 |
false |
|
JavaScript (Defer) | Unblocked (16) |
PRIORITY_NORMAL, 0 |
3 |
false |
|
Font @font-face | TailForbidden (1024) |
PRIORITY_HIGH, -10 |
3 |
false |
Urgency affected by TailForbidden CoS |
Font (rel=preload) | TailForbidden (1024), Unblocked (16) |
PRIORITY_HIGH, -10 fetchpriority=high: PRIORITY_HIGHEST, -20 fetchpriority=low: PRIORITY_LOW, 10 |
2 fetchpriority=high: 1 fetchpriority=low: 4 |
false |
|
Image | (0) |
PRIORITY_LOW, 10 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOWEST, 20 |
5 fetchpriority=high: 3 fetchpriority=low: 6 |
true |
|
Image (rel=preload) | (0) |
PRIORITY_LOW, 10 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOWEST, 20 |
4 fetchpriority=high: 3 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 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOW, 10 |
4 fetchpriority=high: 3 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. |