Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This specification defines the preload
relationship of the HTML Link Element (<link>
).
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.
Many applications require fine-grained control over when resources are fetched, processed, and applied to the document. For example, the loading and processing of some resources may be deferred by the application to reduce resource contention and improve performance of the initial load. This behavior is typically achieved by moving resource fetching into custom resource loading logic defined by the application - i.e. resource fetches are initiated via injected elements, or via XMLHttpRequest
, when particular application conditions are met.
However, there are also cases where some resources need to be fetched as early as possible, but their processing and execution logic is subject to application-specific requirements - e.g. dependency management, conditional loading, ordering guarantees, and so on. Currently, it is not possible to deliver this behavior without a performance penalty.
img
, script
, link
) couples resource fetching and execution. Whereas, an application may want to fetch, but delay execution of the resource until some condition is met.XMLHttpRequest
to avoid above behavior incurs a serious performance penalty by hiding resource declarations from the user agent's DOM parser and preload scanners. The resource fetches are only dispatched when the relevant JavaScript is executed, which due to abundance of blocking scripts on most pages introduces significant delays and affects application performance.The preload
relationship of the HTML Link Element provides a declarative fetch primitive that addresses the above use case of initiating an early fetch and separating fetching from resource execution. As such, preload
relationship serves as a low-level primitive that enables applications to build custom resource loading and execution behaviors without hiding resources from the user agent and incurring delayed resource fetching penalties.
The preload
relationship is used to declare a resource and its fetch properties. Initiating an early fetch allows the application to mask request latency and make it available sooner to the application, which can then decide when and in which order each resource is applied to the current document.
<!-- preload a widget component --> <link rel="preload" href="/components/widget.html" as="iframe"> <!-- preload an application script --> <link rel="preload" href="/app/script.js" as="javascript"> <!-- preload a CSS stylesheet --> <link rel="preload" href="/style/style.css" as="stylesheet"> <!-- preload an image asset --> <link rel="preload" href="//example.com/image.jpg" as="image" media="screen and (max-width: 640px)">
as
attribute, as a resource fetch initiated by the specified context - e.g. a "script" resource specified via preload
relationship MUST be fetched with the same priority and settings as a script fetch initiated via a script
element.load
event of the document unless the preload-initiated fetch is matched with a matching request that blocks the load
event of the document - see 2.4 Matching responses with requests. [HTML5]The crossorigin
CORS setting attribute is an OPTIONAL attribute that indicates the CORS policy of the specified resource. [HTML5]
The as
attribute on a preload
relationship specifies the request context used to initialize appropriate fetch settings - e.g. request priority, HTTP headers, etc. [FETCH]
<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="iframe">
as
attribute is a REQUIRED attribute for a preload
relationship. The specified as
value MUST be a valid request context as defined in [FETCH]. If the as
attribute is omitted, or the specified value does not contain a valid request context, then the user agent SHOULD output a developer-friendly warning and ignore the preload
relationship.as
attribute MUST match the default settings set by the user agent when processing a resource with the same context. This behavior is necessary to guarantee correct prioritization and request matching - see 2.4 Matching responses with requests.as
attribute is only used to initialize appropriate fetch settings; the communicated context is not meant to enforce security or other resource policies.
A preload link is a preload
relationship that is used to indicate a resource that should fetched by the user agent. The preload link's MAY be specified in the document markup, MAY be provided via the HTTP Link
header, and MAY be dynamically added to and removed from the document.
Link: <https://example.com/font.woff>; rel=preload; as=font Link: <https://example.com/app/script.js>; rel=preload; as=script Link: <https://example.com/logo-hires.jpg>; rel=preload; as=image
<link rel="preload" href="//example.com/widget.html" as="iframe">
<script> var res = document.createElement("link"); res.rel = "preload"; res.as = "iframe"; res.href = "/other/widget.html"; document.head.appendChild(res); </script>
The appropriate times to obtain the resource are:
link
element that is already in a Document.href
attribute of the link
element of an preload link that is already in a Document is changed.crossorigin
attribute of the link
element of a preload link that is already in a Document is set, changed, or removed.media
attribute of the link
element of a preload link that is in a Document contains a valid media query that matches the environment of the user. Otherwise, if the media query is invalid, or evaluates to false [mediaqueries-4], the user agent SHOULD NOT obtain the resource.The user agent SHOULD abort the request if the href
attribute on the link
element of an preload link is removed, or its value is set to an empty string.
Once the attempt to obtain the 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.
<script> function preloadFinished(e) { ... } function preloadError(e) { ... } </script> <!-- listen for load and error events --> <link rel="preload" href="app.js" as="script" onload="preloadFinished()" onerror="preloadError()">
load
event on a preload
relation as an indicator that the resource has been successfully fetched and is now ready to be processed by the application - e.g. a stylesheet or script can be applied to a document, and so on, without blocking on the network.
Resources fetched via
relation MUST be retained by the user agent for the duration of the current navigation until they are fetched with a matching request.preload
For example, if a JavaScript resource is fetched via a
relation and the response contains a preload
no-cache
directive, the fetched response is retained by the user agent and is made immediately available when fetched with a matching same navigation 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 preload relation and a later fetch requesting the same resource.
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.
This section is non-normative.
Speculative parsers are used by most user agents to initiate early resource fetches while the main document parser is blocked due to a blocking script. However, these speculative parsers do not execute JavaScript, and typically only perform a shallow parse of CSS, which means that the fetch of resources specified within JavaScript and CSS is delayed until the relevant document parser is able to process the resource declaration.
In effect, most resources declarations specified within JavaScript and CSS are "hidden" from the speculative parsers and incur a performance penalty. To address this, the application can use the preload relation
to declaratively specify which resources the user agent must fetch early to improve page performance.
The preload relation
can be used by the application to initiate early fetch of one or more resources, as well as to provide custom logic for when and how each response should be applied to the document. The application may:
The preload relation
provides a low-level and content-type agnostic primitive that enables applications to build custom resource loading and execution behaviors without incurring the penalty of delayed resource loading.
For example, preload relation
enables the application to provide async
and defer
like semantics, which are only available on script
elements today, but for any content-type: applying the resource immediately after it is available provides async
functionality, whereas adding some ordering logic enables defer
functionality. Further, this behavior can be defined across a mix of content-types - the application is in full control over when and how each resource is applied.
By decoupling resource fetching from execution, the preload relation
provides a future-proof primitive for building performant application specific resource loading strategies.
The preload relation
can be specified by the developer, or be automatically generated by the application server or an optimization proxy (e.g. a CDN).
head
that contains XMLHttpRequest
, image
, and object
requests for the associated critical resources. However, in practice, these implementations are brittle and often result in prioritization conflicts with requests initiated by speculative and document parsers, or worse, result in delayed or double downloads due to missing request context information. The preload relation
addresses these problems by providing a declarative fetch primitive, and interoperability with the HTTP Link header, that communicates both the URL and the context of the resource.This section is non-normative.
This document reuses text from the [HTML] specification, edited by Ian Hickson, as permitted by the license of that specification.