resource_tailing.md (13708B)
Firefox Resource Tailing Documentation
Overview
Resource tailing is a network optimization mechanism in Firefox that delays the loading of certain low-priority resources (typically third-party tracking resources) until higher-priority resources have finished loading. This helps improve page load performance by prioritizing resources that are critical for rendering and user interaction.
For information about how resource tailing integrates with Firefox's overall network scheduling and prioritization system, see Firefox Network Scheduling and Prioritization.
How Resource Tailing Works
The Mechanism
- Tailing A Resource is Eligible for Tailing When: 1.
- Tailing A Resource is Eligible for Tailing When: 1.
- Non-tailed requests are regular resources that load immediately - Tailed requests are delayed resources that are queued until certain conditions are met - The request context maintains a count of active non-tailed requests via AddNonTailRequest() and RemoveNonTailRequest()
- Tailing A Resource is Eligible for Tailing When: 1.
- When a channel marked as "tailable" attempts to open, it calls IsContextTailBlocked() - If the context is in tail-blocked state (has active non-tailed requests), the channel is queued - The channel implements nsIRequestTailUnblockCallback and its OnTailUnblock() method is called when unblocked
- Tailing A Resource is Eligible for Tailing When: 1.
- Time-based: A timer schedules when to unblock tailed requests. The delay is calculated as:
- delay = quantum * mNonTailRequests (with maximum limits)
- Default quantum decreases after DOMContentLoaded
- The delay decreases progressively with time since page load began
- Load completion: When non-tailed request count drops to zero after DOMContentLoaded
- Forced unblocking: When the request context is canceled (e.g., navigation away)
- Tailing A Resource is Eligible for Tailing When: 1.
`
AsyncOpen() or Connect()
→ WaitingForTailUnblock() checks if channel should be tailed
→ If yes: queued via IsContextTailBlocked()
→ mOnTailUnblock callback is set
→ Later: OnTailUnblock() is called
→ Executes the saved callback to continue operation
`
Eligibility for Tailing
A Resource is Eligible for Tailing When:
- Tailing A Resource is Eligible for Tailing When: 1.
- Tailing A Resource is Eligible for Tailing When: 1.
- UrgentStart - User-initiated or high-priority requests
- Leader - Blocking resources in document head
- TailForbidden - Explicitly forbidden from tailing
- Tailing A Resource is Eligible for Tailing When: 1.
- Tailing A Resource is Eligible for Tailing When: 1.
Resources That Are Tailed
Primary Case: Third-Party Tracking Resources
- When: A resource is classified as a third-party tracker (see nsHttpChannel::Connect())
- Detected: via IsThirdPartyTrackingResource() using URL classifier
- Flag added: nsIClassOfService::Tail
Secondary Case: Async Scripts with TailAllowed
- Resource: Async
<script>elements (see ScriptLoader::PrepareRequestPriorityAndRequestDependencies) - Flags:
Unblocked | TailAllowed - Reasoning: Async scripts don't block DOMContentLoaded, so they can be tailed if detected as trackers
Resources That Are NEVER Tailed
1. Navigation Requests
- Resource: Top-level document loads (see HttpBaseChannel::IsNavigation())
- Check:
LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI) - Reason: Primary content must load first
2. Leader Resources (Critical Render-Blocking)
- Resources:
- Non-deferred stylesheets (see Loader::LoadSheetAsyncInternal)
- Synchronous scripts in document <head> that block loading (see ScriptLoader::PrepareRequestPriorityAndRequestDependencies)
- Flag: nsIClassOfService::Leader
- Reason: These block rendering and must load as fast as possible
3. UrgentStart Resources (User-Initiated)
- Resources:
- Fetches triggered during user input events (see FetchDriver::HttpFetch()) - Images loaded with urgent flag during interactions (see ImageLoadTask::mUseUrgentStartForChannel) - Top-level document loads
- Flag: nsIClassOfService::UrgentStart
- Reason: Direct response to user actions must be immediate
4. TailForbidden Resources
- Resources:
- Deferred scripts when tailing is disabled (see ScriptLoader::PrepareRequestPriorityAndRequestDependencies) - Resources explicitly marked to never be tailed
- Flag: nsIClassOfService::TailForbidden
- Reason: These resources need to load to fire DOMContentLoaded
5. Other Unblocked Resources (without TailAllowed)
- Resources:
- Body synchronous scripts and head/body async scripts (see ScriptLoader::PrepareRequestPriorityAndRequestDependencies) - Other resources that shouldn't be blocked by Leaders but also shouldn't be tailed
- Flags:
UnblockedwithoutTailAllowed
6. Resources with TailForbidden Override
- Check: See nsHttpChannel::EligibleForTailing() which checks for
TailForbiddenflag - Any combination of flags with
TailForbiddenprevents tailing
Key Files and Interfaces
Core Interfaces
- [netwerk/base/nsIRequestContext.idl](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/base/nsIRequestContext.idl): Defines the request context interface for managing tail blocking
- [netwerk/base/nsIClassOfService.idl](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/base/nsIClassOfService.idl): Defines class of service flags (Tail, TailAllowed, TailForbidden, Leader, UrgentStart, etc.)
Implementation
- [netwerk/base/RequestContextService.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/base/RequestContextService.cpp): Implements the request context and tail queue management
- [netwerk/protocol/http/nsHttpChannel.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/protocol/http/nsHttpChannel.cpp):
- WaitingForTailUnblock(): Checks if channel should be tailed - EligibleForTailing(): Determines tailing eligibility - OnTailUnblock(): Callback when channel is unblocked - Connect() / AsyncOpen(): Entry points that check for tailing
Resource-Specific Code
- [dom/script/ScriptLoader.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/dom/script/ScriptLoader.cpp): Sets flags for script resources (Leader, TailForbidden, TailAllowed)
- [layout/style/Loader.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/layout/style/Loader.cpp): Sets Leader flag for blocking stylesheets
- [dom/fetch/FetchDriver.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/dom/fetch/FetchDriver.cpp): Sets UrgentStart for user-initiated fetches
- [dom/base/nsImageLoadingContent.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/dom/base/nsImageLoadingContent.cpp): Handles urgent image loading
Classification
- [netwerk/protocol/http/HttpBaseChannel.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/protocol/http/HttpBaseChannel.cpp): IsThirdPartyTrackingResource() determines if a resource is a tracker
- [netwerk/url-classifier/UrlClassifierCommon.cpp](https://searchfox.org/firefox-main/rev/39bc83bb8632d54d70542dc5d98c046a317ec99d/netwerk/url-classifier/UrlClassifierCommon.cpp): URL classification logic for trackers
HTTP/2 Priority Mapping
For HTTP/2 connections (see urgency calculation in nsHttpHandler::UrgencyFromCoSFlags():
- Tailed resources get a special urgency level:
network.http.tailing.urgencypref - See comments in nsIClassOfService.idl for full HTTP/2 priority tree documentation
Configuration Preferences
- `network.http.tailing.enabled`: Master switch for tailing feature
- `network.http.tailing.urgency`: HTTP/2 urgency level for tailed resources
- Delay calculation parameters in nsHttpHandler
Child Process Handling
- Tailing is not supported in child processes (see RequestContext::BeginLoad() and RequestContext::DOMContentLoaded())
- Request context state is synchronized with parent process via Necko IPC
- Actual tail blocking only occurs in the parent process
Summary
Resource tailing intelligently delays low-priority resources (primarily third-party trackers) to improve page load performance. The system uses:
- Actual tail blocking only occurs in the parent process
- Actual tail blocking only occurs in the parent process
- Actual tail blocking only occurs in the parent process
- Actual tail blocking only occurs in the parent process
This creates a more responsive browsing experience by prioritizing resources that matter most to the user while still allowing tracking and analytics resources to eventually load.
Note that on some pages tailing can actually make the pageload slower. See bug 1962817 where the page hides the content until the tracking content loads.