61 lines
8.9 KiB
Markdown
61 lines
8.9 KiB
Markdown
# 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)](https://web.archive.org/web/20201021003137/https://developer.mozilla.org/en-US/docs/Mozilla/Gecko/HTML_parser_threading).
|
|
|
|
### 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](https://searchfox.org/mozilla-central/rev/f549a50b1e39b1e6bea19912d92545c4c0a06b7b/netwerk/base/nsIClassOfService.idl#7-15)
|
|
- Categories (e.g. [Leader, Normal, Follower, Speculative, etc](https://searchfox.org/mozilla-central/rev/f549a50b1e39b1e6bea19912d92545c4c0a06b7b/netwerk/base/nsIClassOfService.idl#69-102)) 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](https://searchfox.org/mozilla-central/rev/f2c181a7ab3bfea4d2266521e6eac713630479b3/netwerk/protocol/http/nsHttpHandler.cpp#794-818)
|
|
|
|
## 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) to `7` (lowest priority). Resources with a lower numerical urgency are delivered before those with higher urgencies. For example, all resources with urgency `2` are transferred before those with urgency `3` 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](https://searchfox.org/mozilla-central/rev/f2c181a7ab3bfea4d2266521e6eac713630479b3/netwerk/protocol/http/nsHttpHandler.cpp#794-818)
|
|
- Use of the [SupportsPriority](https://searchfox.org/mozilla-central/rev/f549a50b1e39b1e6bea19912d92545c4c0a06b7b/xpcom/threads/nsISupportsPriority.idl#8-16) interface.
|
|
- Application of PriorityHints (e.g., `fetchpriority="high"`) [adjustments](https://searchfox.org/mozilla-central/rev/1e8cec3727d6e09f4af41bb3d202b7a4c326ed84/modules/libpref/init/StaticPrefList.yaml#12615-12863) which is implemented via `SupportsPriority`
|
|
- 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](https://searchfox.org/mozilla-central/rev/a13db27562f9237db97e2ea5b01dc879d5b55b74/modules/libpref/init/StaticPrefList.yaml#7429-7431) and [bug 1915817](https://bugzilla.mozilla.org/show_bug.cgi?id=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. |
|
|
|
|
---
|
|
|
|
|
|
---
|