Abstract

This specification defines the preload keyword that may be used with link elements.
This keyword provides a declarative fetch primitive that initiates an early fetch and separates fetching from resource execution.

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 https://www.w3.org/TR/.

This is a work in progress and may change without any notices.

Implementers SHOULD be aware that
this document is not stable. Implementers who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this document before it eventually
reaches the Candidate Recommendation stage SHOULD join the mailing lists below and take part in the discussions.

Publication as a 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.

2. Introduction

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.

Declaring a resource via one of the existing elements (e.g. 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.

Fetching resources with XMLHttpRequest to avoid above behavior incurs a serious performance penalty by hiding resource declarations from the user agent's DOM and preload parsers. 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 keyword on link elements 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 keyword 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.

For example, the application can use the preload keyword to initiate early, high-priority, and non-render-blocking fetch of a CSS resource that can then be applied by the application at appropriate time:

As above examples illustrate, the resource can be specified via declarative markup, Link HTTP header ([RFC5988]), or scheduled via JavaScript. See use cases section
for more hands-on examples of how and where preload can be used.

3. Link type "preload"

The preload keyword may be used with link elements. This keyword creates an external resource link (
preload link) that is used to declare a resource and its fetch properties.

Note: feature detection

If the preload keyword is used as an optimization to initiate earlier fetch then no additional feature detection checks are necessary: browsers that support preload will initiate earlier fetch, and those that do not will ignore it and fetch
the resource as previously. Otherwise, if the application intends to rely on preload to fetch the resource, then it can execute a feature detection
check to verify that it is supported.

Note: relationship to prefetch

Both prefetch and preload declare a resource and its fetch properties, but differ in how and when the resource is fetched by the
user agent: prefetch is an optional and low-priority fetch for a resource that might be used by a subsequent navigation; preload is a mandatory and high-priority fetch for a resource that is necessary for the current navigation. Developers should use each one accordingly to minimize resource contention and optimize load performance.

Once a preload resource has been obtained, the user agent must add request to fetch group's response cache.

Note

In addition to the HTTP cache, all browser implementations provide one or more levels of additional caches, which sometimes live before the HTTP cache (e.g. HTTP/2 server push responses are typically not committed to HTTP cache until
a client request is made), and after the HTTP cache (e.g. in-process memory caches). These caches are not defined today and need to be defined in Fetch API— see related
discussion.

Conceptually, a preloaded response ought to be committed to the HTTP cache, as it is initiated by the client, and also be available in the memory cache and be re-usable at least once within the lifetime of a fetch group.

The user agent MUST NOT automatically execute or apply the resource against the current page context.

Note

For example, if a JavaScript resource is fetched via a
preload link and the response contains a 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 link and a later fetch requesting the same resource.

3.2 as attribute

Note

[HTML] defines the
as content and IDL attributes. The attribute is necessary to guarantee correct prioritization, request matching, application of the correct [CSP3] policy, and setting
of the appropriate Accept request header.

When the resource is declared via the Link header field ([RFC5988]), the resource's as attribute is defined via the as link-extension target attribute.
([RFC5988] section 5.4)

3.3 Server Push (HTTP/2)

HTTP/2 ([RFC7540]) allows a server to pre-emptively send ("push") responses to the client. A pushed response is semantically equivalent to a server responding to a request and, similar
to a preloaded response, is retained by the user agent and executed by the application when matched with a request initiated by the application. As such, from an application perspective, there is no difference between consuming a preload
or a server push response.

The server MAY initiate server push for preload link resources defined by the application for which it is authoritative.
Initiating server push eliminates the request roundtrip between client and server for the declared preload link resource. Optionally, if the use of server push is
not desired for a resource declared via the Link header field ([RFC5988]), the developer MAY provide an opt-out signal to the server
via the nopush target attribute ([RFC5988] section 5.4). For example:

The above example indicates to an HTTP/2 push capable server that /app/style.css should not be pushed (e.g. the origin may have additional information indicating that it may already be in cache), while /app/script.js should be considered as a candidate for server push.

Initiating server push for a preload link is an optional optimization. For example, the server might omit initiating push if it believes that the response is available
in the client's cache: the client will process the preload directive, check the relevant caches, and initiate the request to the server if the resource is missing. Alternatively, the server might omit initiating push due to operational
concerns, such as available server resources or other criteria. Finally, the use of server push is subject to negotiated HTTP/2 connection settings: the client may limit or outright disable the use of server push. Applications cannot rely
on the availability and use of server push.

4. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST NOT, and SHOULD are to be interpreted as described in [RFC2119].

There is only one class of product that can claim conformance to this specification: a user agent.

A. Use cases

This section is non-normative.

A.1 Early fetch of critical resources

Preload 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, the preload 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 a preload link to declaratively specify which resources the user agent must fetch early to improve page performance:

Above markup initiates four resource fetches: a font resource, a stylesheet, an unknown resource type from another origin, and a font resource from another origin. Each fetch is initialized with appropriate request headers and priority - the
unknown type is equivalent to a fetch initiated XMLHttpRequest request. Further, these requests do not block the parser or the load event.

Note

Preload links for CORS enabled resources, such as fonts or images with a crossorigin attribute, must also include a
crossorigin attribute, in order for the resource to be properly used.

A.2 Early fetch and application defined execution

The preload link 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:

Decide to immediately apply each resource as it becomes available.

Ensure that resources are applied in some application specific order.

Apply resources conditionally based on arbitrary resource or application criteria.

Defer resource application until some application condition is met.

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

The optimization proxy to fetch the critical resources and place them into its cache ahead of time, thus reducing or eliminating the latency of retrieving resources from origin.

The optimization proxy can specify preload links on behalf of the application:

The proxy can observe and infer critical resources based on past request patterns, allowing it to automate generation of relevant preload links to improve page performance.

The proxy can deliver inferred preload links to the user agent while it is blocked on the response from the origin, allowing the user agent to begin early fetch of associated critical resources.

Many existing optimization proxies implement "early flush" strategies where references to associated critical resources are automatically delivered to the user agent while the proxy is blocked on the response from the origin.
Today, this is typically done by creating a fake document 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 link 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.

B. IANA Considerations

The link relation type below has been registered by IANA per Section 6.2.1 of [RFC5988]:

Relation Name:

preload

Description:

Refers to a resource that should be loaded early in the processing of the link's context, without blocking rendering.

C. Privacy and Security

This section is non-normative.

Preload is a declarative fetch primitive that initiates early fetch of resources and separates fetching from resource execution. In effect, it is conceptually similar to initiating a scripted fetch for a resource, but with additional constraints
and benefits:

The resource declaration is visible via HTTP headers or HTML markup, which allows the user agent to initiate the fetch earlier, and without blocking on JavaScript execution.

The response is not executed and there is no callback to retrieve its payload. The response is retrieved and executed by initiating another fetch (via script, DOM element, etc) that matches the preloaded response.

The developer can specify the target context that will consume the response via as attribute, which allows the user agent to enforce the relevant CSP policies when initiating the preload fetch. If as is omitted, preload
defaults to same security and privacy processing as a call to fetch() - i.e. subject to connect-src.

The site authors are encouraged to take the necessary precautions and specify the relevant [CSP3], [MIXED-CONTENT], and [REFERRER-POLICY]
rules, such that the browser can enforce them when initiating the preload request. Additionally, if preload directives are provided via the Link HTTP response header, then the relevant policies should also be delivered as an HTTP
response header - e.g. see
Processing Complications for CSP.

D. Acknowledgments

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.