To the extent possible under law, the editors have waived all copyright and related or neighboring rights to this work. In addition, as of 29 September 2014, the editors have made this specification available under the Open Web Foundation Agreement Version 1.0, which is available at http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0. Parts of this work may be from another specification document. If so, those parts are instead covered by the license of that specification document.
Moved to: w3c.github.io/resource-hints.
Modern browsers leverage a wide variety of speculative optimization techniques to anticipate user input and intent, which allows them to hide some of the networking, processing, and rendering latencies: preconnects, early fetching of resources, and prefetching and processing of resources for subsequent navigation.
The decision to initiate one or more of the above optimization is typically based on heuristic rules based on document markup and structure, navigation history, and context of the user - e.g. type of device, available compute and memory resources, network connectivity, user preferences, and so on. These techniques have proven to be successful, but can be further improved by leveraging the application and page specific knowledge of the developer or the servers responsible for generation and delivery of these resources.
For example, the application may provide the following resource hints to the user agent:
Many web applications already leverage a variety prefetching techniques, such as using XMLHttpRequest
to prefetch and cache assets before they are needed. However, these implementations are app-specific, are not interoperable with the browser-provided primitives, and do not provide the same level of performance, or worse, conflict and result in delayed or unnecessary downloads that degrade overall page performance.
This specification defines preconnect
, preload
, and prerender
hints that the developer, or the server generating or delivering the resources, can use in an interoperable way to assist the user agent in the decision process of which origins it should connect to, which resources it should fetch to improve performance, and which resources may be required by the next navigation.
Resource hints are used to assist the user agent in the decision making process of which optimizations can be applied when the page is being loaded, or as the user is interacting with the application.
The preconnect
hint is used to indicate an origin that will be used to fetch required resources. Initiating an early connection, which includes the DNS lookup, TCP handshake, and optional TLS negotiation, allows the user agent to mask the high costs of connection establishment latency.
<link rel="preconnect" href="//example.com"> <link rel="preconnect" href="//cdn.example.com">
The optimal number of connections per origin is dependent on the negotiated protocol, users current connectivity profile, available device resources, and other context specific variables. As a result, this decision is deferred to the user agent, which is in the best position to determine the optimal number.
The user agent should perform the full connection handshake (DNS+TCP for HTTP, and DNS+TCP+TLS for HTTPS origins) whenever possible, but is allowed to elect to perform a partial handshake (DNS only for HTTP, and DNS or DNS+TCP for HTTPS origins), or skip it entirely, due to resource constraints or other reasons.
preconnect
hint can be used to initiate an early connection handshake such that when the resource URL is determined, the user agent can dispatch the request without first blocking on connection negotiation.
Note that this behavior requires ability to dynamically inject a preconnect hint (e.g. as part of a JavaScript handler), and for the preconnect processing to proceed across page navigations.
The preload
hint is used to indicate the URL of a resource that should be fetched as early as possible by the user agent. Initiating an early fetch allows the user agent to mask the request latency of the resource and make it available sooner to the application.
<link rel="preload" href="/assets/font.woff" as="font"> <link rel="preload" href="/assets/logo.webp" as="image"> <link rel="preload" href="//example.com/app.js" as="script"> <link rel="preload" href="//example.com/mobile-ui-framework.js" as="script" media="screen and (max-width: 640px)">
as
attribute is used to indicate the resource destination context - see §3.1 Fetch settings.
load
event of the document unless it is matched with a matching request, and the user agent must fire a simple event indicating the status of the fetch attempt (see §3.3 Hint execution).
preload
hint can be used by the application to initiate early fetch, but delay processing of the received response - e.g. fetch a CSS stylesheet and apply it at some later time, fetch a JavaScript asset and execute it later, and so on. The preload
fetches do not block the document load
event and allow the application to determine which resources are applied, when they are executed, and in which order.
preload
hint the application can declaratively specify which resources the user agent should fetch early to mask the request latency and improve page performance.
preload
hint can be generated both by the application and an optimization proxy (e.g. a CDN) to accelerate fetch and delivery of required resources.
preload
hints, allowing:
preload
hints on behalf of the application:
preload
hints to improve performance.
preload
hints to the user agent while it is blocked on the response from the origin, allowing the user agent to begin fetching required resources.
<head>
that contains XHR, image, and object requests. However, in practice, these implementations often result in prioritization conflicts with requests initiated by speculative and document parsers, or worse, result in delayed or double downloads due to missing context information.
The preload
hint addresses these problems by providing a declarative hint that communicates both the URL and the context of the resource.
The prerender
hint is used to indicate the URL and the context of a resource required by the next navigation. Initiating an early fetch of the specified resource allows the user agent to mask the request latency, and optional preprocessing of the fetched response allows the user agent to deliver an experience of instant delivery and execution once the resource is requested.
<link rel="prerender" href="//example.com/thankyou.html"> <link rel="prerender" href="//example.com/application.js" as="script"> <link rel="prerender" href="//example.com/image.webp" as="image" media="max-width: 640px">
Note: prerender
is not restricted to HTML and may be used to load and preprocess any content-type.
The user agent may perform appropriate preprocessing depending on the type and destination context of the response - e.g. decode an image, parse the HTML markup, parse the HTML markup and initiate fetches for critical subresources, and so on. The decision for which preprocessing steps are performed is deferred to the user agent and is a function of runtime context and specified hint probability - see §3.2 Required vs. speculative hints.
Prerendering should not negatively impact the performance of the current navigation context. Due to the need to fetch and optionally preprocess the specified resource and its associated assets, prerendering may result in high contention for CPU, GPU, memory, and network resources. As a result, the user agent may implement various strategies to minimize resource contention based on type and context of fetched response, impose limits on the properties of the resource that is being prerendered, and so on:
prerender
resource is dependent on the negotiated protocol, users current connectivity profile, available device resources, and other context specific variables. As a result, this decision is deferred to the user agent, which is in the best position to determine the optimal time - e.g. the user agent may decide to wait until all other downloads are finished, or choose to pipeline requests with low priority if the negotiated protocol supports the necessary primitives.
prerender
requests should be lower than that of resources required by the current navigation context.
Note: The above examples are not an exhaustive list. The decision which strategies to implement for each content-type and how to enforce them is deferred to the user agent. For a hands-on example of HTML prerendering strategies, see Chromium prerendering wiki page.
The user agent should not cancel outstanding prerender
requests when a new navigation is triggered as they may be required by the next page. However, the user agent may cancel these requests once it determines that they are not required by the new destination.
To ensure compatibility and improve the success rate of prerender
requests the target page should use the [PAGE-VISIBILITY] to determine the visibility state of the page as it is being rendered and implement appropriate logic to avoid actions that may cause the prerender
to be abandoned (e.g. non-idempotent requests), or unwanted side-effects from being triggered (e.g. analytics beacons firing prior to the page being displayed).
prerender
hint can be used to implement a prefetch strategy that leverages app-specific knowledge about the next navigation based on content, structure, analytics, or other signals - e.g. high-likelihood search results, paginated content or step-driven flows, aggregated analytics or per-user behavior, and so on.
For example, an image gallery may have knowledge about the likelihood of the next photo or page that may be requested by the user. To provide an improved experience the application can ask the user agent to begin fetching required resources (individual photos, critical resources, or the full page) before the next navigation is triggered.
Alternatively, instead of anticipating user activity, the application can react to user input and dynamically schedule prerender requests based on its knowledge of resources that will be required by the next navigation target - i.e. the application may capture a click event and provide prerender
hints to the user agent before the current page is unloaded.
Specifying the as
attribute allows the developer to communicate the resource destination context, such that the user agent can initialize the appropriate fetch settings: HTTP headers, request priority, and so on.
<link rel="preload" href="/assets/font.woff" as="font"> <link rel="preload" href="/assets/logo.webp" as="image"> <link rel="preload" href="//example.com/widget">
as
value must be a valid request context as defined in [FETCH].
as
attribute is missing, the user agent should assign a default context.
as
attribute must match the default settings set by the user agent when processing a resource with the same context - this is necessary to guarantee correct prioritization and request matching (see §3.6 Matching hint responses with requests).
In addition to the fetch settings set by the resource destination context, the user agent must account for the relative hint priority: preload
requests must have higher priority than prerender
requests with the same context. In the case where the same resource has mixed prioritization hints, the user agent should resolve the conflict:
as
attribute is used to initialize appropriate fetch settings; the communicated context should not be used to enforce security or other resource policies.
In addition to specifying the hint type, its fetch parameters, and the resource URL, the developer can communicate the expected probability that the resource will be used in the current or next navigation context.
<link rel="preconnect" href="//sub.example.com" probability="0.22"> <link rel="preload" href="//example.com/application.js" probability="0.75"> <link rel="prerender" href="//example.com/thankyou.html" probability="1.0">
The probability
attribute is a float value in the [0.0-1.0]
range:
1.0
that must be processed by the user agent.
<1.0
that should be processed by the user agent.
probability
attribute is omitted, the hint is considered to be a speculative hint and the user agent may use own heuristics to assign a default probability value.
Speculative hints are processed on a best effort basis by the user agent based on the runtime context of the user agent — availability of CPU, GPU, memory, and networking resources — developer specified probability indicating the likelihood of that resource being used, and specified user preferences.
preconnect
may fallback to a partial handshake (DNS only, or DNS+TCP for HTTPS origins).
preload
may fallback to preconnect
for specified origin.
prerender
may fallback to a mixed strategy for the target resource, and if applicable, its subresources: preconnect
only; fetch
the target resource but defer fetch of subresources; fetch
subresources but delay their processing, and so on.
preload
to preconnect
, prerender
to preload
, performing a partial prerender
, and so on.
Performing a partial optimization allows the user agent to improve performance even if a full optimization cannot be performed. Conversely, on a device with sufficient resources, the user agent may execute all of the specified hints as far as possible.
The user agent must not delay the load
event of the document unless the hint-initiated fetch is matched with a matching request that blocks the load
event of the document.
Once the the attempt to obtain the hint-initiated resource is complete, the user agent must, if the fetch was successful, queue a task to fire a simple event named load
at the link element, or, if the fetch failed to complete for any reason, queue a task to fire a simple event named error
at the link element.
load
event on the link element is an indicator that the hint was processed to completion.
load
event on the link element is an indicator that the user agent has performed full or partial processing on the hint (see §3.2 Required vs. speculative hints).
<script> function hintLoaded() { ... } function hintError() { ... } var hint = document.createElement("link") hint.setAttribute("rel", "preload") hint.setAttribute("as", "image") hint.setAttribute("href", "/image.jpeg") document.getElementsByTagName("head")[0].appendChild(hint) // listen for load/error events hint.addEventListener("load", function() { hintLoaded() }) hint.addEventListener("error", function() { hintError() }) </script> <!-- listen for load/error events --> <link rel="preload" href="app.js" as="script" onload="hintLoaded()" onerror="hintError()">
load
and error
events are not guaranteed to fire for a speculative hint, and when they do, do not guarantee that full processing was applied.
load
event on a preload
hint as an indicator that the resource has been successfully fetched and is now ready to be processed by the application - e.g. the image is ready to be decoded, a stylesheet or script may be applied, and so on, without blocking on the network.
In addition to the hints specified in the document markup, the application may have runtime resource hints based on user context or other signals. The user agent should process dynamically inserted resource hints in addition to and in the same way as document specified hints.
// insert new prerender hint var hint = document.createElement("link") hint.setAttribute("rel", "prerender") hint.setAttribute("href", "/article/part3.html") document.getElementsByTagName("head")[0].appendChild(hint) // cancel prerender document.getElementsByTagName("head")[0].removeChild(hint);
The removal of the hint from the document should cancel the optimization if it is being processed and prevent it from executing if it has not yet been invoked.
The user agent should process resource hints specified via the Link
HTTP header.
Link: <https://example.com>; rel=preconnect Link: <https://example.com/font.woff>; rel=preload; as=font Link: <https://example.com/article/part2.html>; rel=prerender Link: <https://example.com/logo-hires.jpg>; rel=prerender; as=image; media=min-resolution:2dppx
The application may provide one or more of the same type of hint via multiple HTTP headers or via a comma separated list. The user agent should process such hints in addition to and in the same way as document specified and dynamically scheduled resource hints.
Link
header allows automated optimization services running on origin or upstream servers (e.g. CDN) to leverage and emit resource hints without modifying the delivered response.
Resources fetched via preload
and prerender
are retained by the user agent until they are fetched with a matching request. The user agent may decide to discard the retained response due to resource constraints, a timeout (recommended, at least 300 seconds), or other reasons.
preload
and the response contains a no-cache
directive. The fetched response is retained by the user agent and is immediately returned when fetched with a matching request at a later time - e.g. via a script
tag or other means. This ensures that the user agent does not incur an unnecessary revalidation, or a duplicate download, between the initial resource fetch initiated via the specified resource hint and a later fetch requesting the same resource.
Note: "matching" is not currently defined or interoperable across user agents. This should be fixed, but it is out of scope of this specification. For further discussion see this bug and chromium discussion.
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with class="example"
, like this:
Informative notes begin with the word “Note”
and are set apart from the normative text with class="note"
, like this:
Note, this is an informative note.
No properties defined.