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
Request Context: Each page load has an associated nsIRequestContext that tracks the state of all network requests belonging to that context.
Tailed vs Non-Tailed Requests:
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()
Tail Blocking Logic (see RequestContext::IsContextTailBlocked():
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
Unblocking Conditions:
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)
Implementation Flow
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:
Has the nsIClassOfService::Tail flag set
Does NOT have any of these flags:
UrgentStart- User-initiated or high-priority requestsLeader- Blocking resources in document headTailForbidden- Explicitly forbidden from tailing
If marked
Unblocked, must also haveTailAllowedflagIs NOT a navigation request (IsNavigation() returns false)
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 | TailAllowedReasoning: Async scripts don’t block DOMContentLoaded, so they can be tailed if detected as trackers
Resources That Are NEVER Tailed
2. Leader Resources (Critical Render-Blocking)
Resources:
Non-deferred stylesheets (see Loader::LoadSheetAsyncInternal)
Synchronous scripts in document
<head>that block loading (see ScriptLoader::PrepareRequestPriorityAndRequestDependencies)
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
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
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
TailForbiddenflagAny combination of flags with
TailForbiddenprevents tailing
Key Files and Interfaces
Core Interfaces
netwerk/base/nsIRequestContext.idl: Defines the request context interface for managing tail blocking
netwerk/base/nsIClassOfService.idl: Defines class of service flags (Tail, TailAllowed, TailForbidden, Leader, UrgentStart, etc.)
Implementation
netwerk/base/RequestContextService.cpp: Implements the request context and tail queue management
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: Sets flags for script resources (Leader, TailForbidden, TailAllowed)
layout/style/Loader.cpp: Sets Leader flag for blocking stylesheets
dom/fetch/FetchDriver.cpp: Sets UrgentStart for user-initiated fetches
dom/base/nsImageLoadingContent.cpp: Handles urgent image loading
Classification
netwerk/protocol/http/HttpBaseChannel.cpp: IsThirdPartyTrackingResource() determines if a resource is a tracker
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.urgencyprefSee comments in nsIClassOfService.idl for full HTTP/2 priority tree documentation
Configuration Preferences
network.http.tailing.enabled: Master switch for tailing featurenetwork.http.tailing.urgency: HTTP/2 urgency level for tailed resourcesDelay 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:
Class of Service flags to mark resource priority and tailing eligibility
Request Contexts to manage tail queues per page load
Time-based and load-based heuristics to determine when to unblock
Strict rules to ensure critical resources (navigations, Leaders, UrgentStart) are never delayed
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.