Abstract

This specification defines preconnect and preload 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, and which resources it should fetch to improve page performance.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Performance Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-web-perf@w3.org (subscribe, archives). All comments are welcome.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 August 2014 W3C Process Document.

Table of Contents

1. Introduction

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 preloading 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. Worse, these implementations sometimes conflict with the browser logic and result in delayed or unnecessary resource fetches that degrade overall page performance.

This specification defines preconnect and preload 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, and which resources it should fetch to improve page performance.

2. Resource Hints

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.

2.1 Preconnect

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.

Example 1
<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.

2.2 Preload

The preload hint is used to indicate the URL of a resource that should be fetched by the user agent to improve page performance: initiate an early fetch to mask request latency and make it available sooner to the application, or fetch a resource that may be required by the next user action or navigation such that it can deliver an instant response once the resource is requested.

Example 2
<!-- fetch immediately + preprocess if possible -->
<link rel="preload" href="/assets/logo-small.jpeg" as="image" media="screen and (max-width: 640px)">

<!-- fetch immediately + do not preprocess -->
<link rel="preload" href="/components/widget.html" as="html" loadpolicy="inert">

<!-- low-priority fetch + preprocess if possible -->
<link rel="preload" href="//example.com/next-page.html" as="html" loadpolicy="next">

<!-- low-priority fetch + do not preprocess -->
<link rel="preload" href="//example.com/next-component.html" as="html" loadpolicy="next inert">
Note
The next inert loadpolicy is semantically equivalent to rel=prefetch implemented by some browsers; next loadpolicy is semantically equivalent to rel=prerender implemented by some browsers. The preload hint standardizes and extends previous prefetch and prerender hints with more flexible fetch and processing policies.

2.2.1 Fetch settings

Specifying the as attribute allows the developer to communicate the resource destination context, such that the user agent can initialize the appropriate fetch settings: relative request priority, appropriate HTTP headers, and so on.

Example 3
<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">
  • The specified as value must be a valid request context as defined in [FETCH].
  • If the as attribute is missing, the user agent should assign a default context.
  • Request defaults set by the user agent via 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.5 Matching hint responses with requests).
Note
The resource destination context communicated via the as attribute is only used to initialize appropriate fetch settings; the communicated context is not meant to enforce security or other resource policies.

2.2.2 Load and processing policy

The loadpolicy attribute consists of a space-separated set of the following keywords that determine the load and processing policy of the specified resource:

  • next: indicates that the specified resource may be required by the next navigation context, and that the user agent should fetch the resource if possible.
  • inert: indicates that the user agent should not apply any preprocessing on the response - e.g. decode an image ahead of time, preparse HTML markup, parse the HTML markup and fetch and apply resources (i.e. render the next page), and so on.
Example 4
<link rel="preload" href="/assets/font.woff" as="font" loadpolicy="next">
<link rel="preload" href="/assets/logo.webp" as="image" loadpolicy="next inert">
<link rel="preload" href="//example.com/widget">
Note
An empty loadpolicy indicates that the resource is required for the current navigation context, and that the user agent may apply relevant preprocessing to optimize page performance.

Preload initiated resource fetches 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, preloading may result in high contention for the CPU, GPU, memory, and network resources. To address this, the user agent must take into account the specified loadpolicy:

  • Resource fetches with next loadpolicy must have lower relative priority and should not block or interfere with resource fetches required by the current navigation context.
  • The optimal time to initiate a preload resource fetch is dependent on the specified loadpolicy, negotiated transport protocol, users current connectivity profile, available device resources, and other context specific variables.
    • If next keyword is omitted, the user agent must initiate the fetch as soon as possible.
    • If next keyword is present, the user agent should determine the optimal time and initiate the fetch - 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. Alternatively, the user agent may opt-out from initiating the fetch due to resource constraints, user preferences, or other factors.
  • By default, the user agent may perform appropriate preprocessing on the preloaded resource depending on the type and destination context of the response. Preprocessing prepares the resource to be applied, but it does not automatically execute or apply it against the current page context.
    • The decision for which preprocessing steps are performed is deferred to the user agent.
    • The user agent must not apply any preprocessing when the inert keyword is present - e.g. the developer may want to opt-out from preprocessing the next HTML document and its subresources.

The user agent should perform preprocessing of applicable resources, and may implement various strategies to minimize resource contention based on the type and context of fetched response, impose limits on the properties of the resource that is being preloaded, and so on:

  • Preprocessing may be allocated fewer CPU, GPU, or memory resources.
  • When preprocessing an HTML document, some resource requests may be delayed until the preloaded resource is made visible - e.g. media downloads, plugin content, and so on.
  • Preprocessing may be abandoned due to resource constraints.
    • Limited available resources may prevent preprocessing from being initiated.
    • High resource requirements of the preloaded content may lead the user agent to cancel preprocessing - e.g. exceeded memory requirements, high CPU usage, and so on.
  • Preprocessing may be abandoned based on the type or properties of the preloaded content. For example, when preprocessing an HTML response:
    • If the target exhibits non-idempotent behavior: mutations to shared local storage, XMLHttpRequest with a verb other than GET, HEAD, or OPTION, and so on.
    • If the target triggers a condition that requires user input: confirmation dialogs, authentication prompts, alerts, and so on.

The above processing strategies 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.

Note
To ensure compatibility and improve the success rate of speculative preload 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 preload 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).
Note
TODO: Resource hints are subject to media query processing: the user agent must initiate resource fetch when media attribute's value matches the environment, and must not initiate the fetch otherwise.

3. Processing model

3.1 Required vs speculative hints

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.

Example 5
<link rel="preconnect" href="//sub.example.com" pr="0.22">
<link rel="preload" href="//example.com/application.js" pr="0.75">
<link rel="preload" href="//example.com/thankyou.html">

The pr attribute is a float value in the [0.0-1.0] range:

If the pr attribute is omitted, the hint is considered to be a required hint (i.e. it has a probability of 1.0), unless the loadpolicy contains the next keyword. 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.

Note

To optimize the overall user experience the user agent should account for local context and specified probability of a speculative hint. For example, on a resource constrained device the user agent may decide to only execute high probability hints. Alternatively, it may decide to perform partial processing of the hint, such as downgrading preload to preconnect, performing partial preprocessing, 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.

3.2 Hint execution

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 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.

Example 6
<script>
function hintLoaded() { ... }
function hintError()  { ... }

var hint = document.createElement("link");
hint.setAttribute("rel", "preload");
hint.setAttribute("as", "image");
hint.setAttribute("href", "/image.jpg");
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()">
Note
The decision on whether a speculative hint is executed, and if so, whether full or partial processing is applied is deferred to the user agent. As a result, the 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.
The application may use the 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.

3.3 Dynamic scheduling

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.

Example 7
// insert new preload hint
var hint = document.createElement("link");
hint.setAttribute("rel", "preload");
hint.setAttribute("loadpolicy", "next");
hint.setAttribute("href", "/article/part3.html");
document.getElementsByTagName("head")[0].appendChild(hint);

// cancel preload
document.getElementsByTagName("head")[0].removeChild(hint);

The removal of the hint from the document must cancel the optimization if it is being processed and prevent it from executing if it has not yet been invoked.

The application may use dynamic scheduling to react and adapt to user initiated actions - e.g. initiate a speculative resource fetch in response to recent user activity, cancel previous speculative fetch, and so on.

3.5 Matching hint responses with requests

Resources fetched via preload 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.

A JavaScript resource is fetched via 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
The concept of "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.

4. Use cases

4.1 Dynamic request URL (preconnect)

The full resource URL may not be known until the page is being constructed by the user agent - e.g. conditional loading logic, UA adaptation, etc. However, the origin from which one or more of these resources will be fetched is often known ahead of time by the developer or the server generating the response. In such cases, a 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.

4.2 Anonymizing redirect (preconnect)

Many sites rely on redirects for analytics and to anonymize the referrer before sending the user to the final destination. Because the destination is known ahead of time, a preconnect hint can be used to initiate the connection handshake with the destination origin in parallel with the processing of the redirect. Note that this behavior requires ability to dynamically inject the hint (e.g. as part of a JavaScript handler), and for the preconnect processing to proceed across page navigations.

4.3 Early fetch of critical resources (preload)

Speculative parsers do not execute JavaScript and perform a shallow parse of CSS, which means that the fetch of resources specified within JavaScript and CSS is delayed until the document parser is able to process the resource declaration. By using a preload hint the application can declaratively specify which resources the user agent should fetch early to mask the request latency and improve page performance.

4.4 Early fetch with on-demand processing (preload)

The 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. 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.

4.5 Developer, server, and proxy-generated hints (preload)

The 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.

  1. The application can specify preload hints, allowing:
    • The optimization proxy to initiate early fetch of the associated resources and place them into its cache, thus reducing or eliminating the latency of retrieving resources from the origin.
    • The user agent to initiate early fetch of required resources - see example above.
  2. The optimization proxy can specify preload hints on behalf of the application:
    • The proxy can observe and infer required resources based on past request patterns, allowing it to automate generation of relevant preload hints to improve performance.
    • The proxy can deliver inferred 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.

Many optimization proxies already implement the "early flush" strategy where references to required resources are delivered to the user agent while the proxy is blocked on the response from the origin. Today, this is typically done by synthesizing a document header 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.

4.6 Speculative fetching (preload)

The preload 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 preload 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 preload hints to the user agent before the current page is unloaded.

A. Acknowledgments

This document reuses text from the [HTML] specification, edited by Ian Hickson, as permitted by the license of that specification.

B. References

B.1 Normative references

[RFC5988]
M. Nottingham. Web Linking. October 2010. Proposed Standard. URL: http://www.ietf.org/rfc/rfc5988.txt

B.2 Informative references

[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Ian Hickson. HTML. Living Standard. URL: https://html.spec.whatwg.org/
[PAGE-VISIBILITY]
Jatinder Mann; Arvind Jain. Page Visibility (Second Edition). 29 October 2013. W3C Recommendation. URL: http://www.w3.org/TR/page-visibility/