8.9 KiB
8.9 KiB
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
). - 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 fetchpriority=high: PRIORITY_HIGH, -20 fetchpriority=low: PRIORITY_LOW, 0 |
2 fetchpriority=high: 0 fetchpriority=low: 2 |
false |
|
CSS (rel=preload) | Leader (1) |
PRIORITY_HIGHEST, -20 fetchpriority=high: PRIORITY_HIGH, -20 fetchpriority=low: PRIORITY_LOW, -10 |
0 fetchpriority=high: 0 fetchpriority=low: 1 |
false |
|
CSS (Body) | Leader (1) |
PRIORITY_NORMAL, 0 fetchpriority=high: PRIORITY_HIGH, -20 fetchpriority=low: PRIORITY_NORMAL, 0 |
2 fetchpriority=high: 0 fetchpriority=low: 2 |
false |
|
JavaScript (Blocking) | Leader (1) |
PRIORITY_NORMAL, 0 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOW, 10 |
2 fetchpriority=high: 1 fetchpriority=low: 3 |
false |
|
JavaScript (rel=preload) | Unblocked (16) |
PRIORITY_HIGHEST, -20 fetchpriority=high: PRIORITY_HIGH, -20 fetchpriority=low: PRIORITY_LOW, 10 |
1 fetchpriority=high: 1 fetchpriority=low: 4 |
false |
|
JavaScript (Async) | TailAllowed (512), Unblocked (16) |
PRIORITY_NORMAL, 0 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOW, 10 |
3 fetchpriority=high: 2 fetchpriority=low: 4 |
false |
|
JavaScript (Defer) | Unblocked (16) |
PRIORITY_NORMAL, 0 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOW, 10 |
3 fetchpriority=high: 2 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 fetchpriority=high: PRIORITY_HIGH, -10 fetchpriority=low: PRIORITY_LOW, 10 |
2 fetchpriority=high: 2 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. |