Copyright © 2018 W3C ® ( MIT , ERCIM , Keio , Beihang ). W3C liability , trademark and permissive document license rules apply.
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.
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.
This
document
was
published
by
the
Web
Performance
Working
Group
as
an
Editor's
Draft.
Comments
regarding
this
document
are
welcome.
Please
send
them
to
public-web-perf@w3.org
(
subscribe
,
archives
)
with
[preload]
at
the
start
of
your
email's
subject.
Publication as an Editor's 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 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 March 2017 W3C Process Document .
The terms link , inserted into a document , resolve , url , crossorigin , origin , delay the load event , external resource link , valid media query list , queue a task and obtain the resource are defined in [ HTML ].
The terms match the environment are defined in [ HTML52 ].
The terms Document , Content-Type metadata , fire an event , in a document tree and node document are defined in [ DOM ].
The term request destination is defined in [ FETCH ].
The terms parsable MIME type and unsupported MIME type are defined in [ MIMESNIFF ].
The
term
prefetch
is
defined
in
[
RESOURCE-HINTS
].
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
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:
<!-- preload stylesheet resource via declarative markup -->
<link rel="preload" href="/styles/other.css" as="style">
<!-- or, preload stylesheet resource via JavaScript -->
<script>
var res = document.createElement("link");
res.rel = "preload";
res.as = "style";
res.href = "styles/other.css";
document.head.appendChild(res);
</script>
Link: <https://example.com/other/styles.css>; rel=preload; as=style
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.
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.
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.
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.
The appropriate times to obtain the resource are:
Link
headers
that
contain
a
preload
link
.
href
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
is
changed.
crossorigin
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
is
set,
changed,
or
removed.
as
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
is
set
or
changed
to
a
value
that
does
not
or
no
longer
matches
the
request
destination
of
the
previous
obtained
external
resource,
if
any.
as
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
but
was
previously
not
obtained
due
to
the
as
attribute
specifying
an
unsupported
request
destination
is
set,
removed,
or
changed.
type
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
but
was
previously
not
obtained
due
to
the
type
attribute
not
specifying
a
parsable
MIME
type
or
specifying
an
unsupported
MIME
type
for
the
request
destination
is
set,
removed,
or
changed.
media
attribute
of
the
link
element
of
a
preload
link
that
is
already
in
a
document
tree
but
was
not
previously
obtained
due
the
media
attribute's
value
being
not
a
valid
media
query
list
or
one
that
does
not
match
the
environment
is
set,
removed,
or
changed.
The
user
agent
SHOULD
abort
the
current
request
if
the
href
attribute
of
the
link
element
of
a
preload
link
is
changed,
removed,
or
its
value
is
set
to
an
empty
string.
At these times, the user agent must obtain the resource given by the link element.
Obtaining the resource given by a preload link element MUST NOT delay the load event of the element's node document .
Once a preload resource has been obtained , the user agent must add request to fetch group's response cache.
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.
Link HTTP response header should be processed for all types of request destination .
When
the
media
attribute's
value
does
not
match
the
environment
,
the
resource
will
not
be
preloaded.
The user agent MUST NOT automatically execute or apply the resource against the current page context.
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.
as
attribute
[
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)
Example directives to preload a resource that will be consumed by...
consumer | Preload directive |
---|---|
<audio>
|
<link
rel=preload
as=audio
href=...>
|
<video>
|
<link
rel=preload
as=video
href=...>
|
<track>
|
<link
rel=preload
as=track
href=...>
|
<script>
,
Worker's
importScripts
|
<link
rel=preload
as=script
href=...>
|
<link
rel=stylesheet>
,
CSS
@import
|
<link
rel=preload
as=style
href=...>
|
CSS @font-face |
<link
rel=preload
as=font
href=...>
|
<img>
,
<picture>
,
srcset,
imageset
|
<link
rel=preload
as=image
href=...>
|
SVG's
<image>
,
CSS
*-image
|
<link
rel=preload
as=image
href=...>
|
XHR, fetch |
<link
rel=preload
as=fetch
crossorigin
href=...>
|
Worker, SharedWorker |
<link
rel=preload
as=worker
href=...>
|
<embed>
|
<link
rel=preload
as=embed
href=...>
|
<object>
|
<link
rel=preload
as=object
href=...>
|
<iframe>
,
<frame>
|
<link
rel=preload
as=document
href=...>
|
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:
Link: </app/style.css>; rel=preload; as=style; nopush
Link: </app/script.js>; rel=preload; as=script
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.
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 .
This section is non-normative.
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:
<link rel="preload" href="/assets/font.woff2" as="font" type="font/woff2">
<link rel="preload" href="/style/other.css" as="style">
<link rel="preload" href="//example.com/resource" as="fetch" crossorigin>
<link rel="preload" href="https://fonts.example.com/font.woff2" as="font" crossorigin type="font/woff2">
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.
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.
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:
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.
<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()">
By decoupling resource fetching from execution, the preload link provides a future-proof primitive for building performant application specific resource loading strategies.
The preload link can be specified by the developer, or be automatically generated by the application server or an optimization proxy (e.g. a CDN).
Link: <https://example.com/font.woff2>; rel=preload; as=font; type="font/woff2"
Link: <https://example.com/app/script.js>; rel=preload; as=script
Link: <https://example.com/logo-hires.jpg>; rel=preload; as=image
Link: <https://fonts.example.com/font.woff2>; rel=preload; as=font; crossorigin; type="font/woff2"
<link rel="preload" href="//example.com/widget.html" as="document">
<script>
var res = document.createElement("link");
res.rel = "preload";
res.as = "document";
res.href = "/other/widget.html";
document.head.appendChild(res);
</script>
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.
The link relation type below has been registered by IANA per Section 6.2.1 of [ RFC5988 ]:
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:
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.
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.