Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define behavior of <link rel=preload> in detail #7260

Merged
merged 12 commits into from
Nov 30, 2021
Merged
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 185 additions & 39 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2152,6 +2152,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x-href="https://infra.spec.whatwg.org/#scalar-value">scalar value</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#tuple">tuple</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#noncharacter">noncharacter</dfn></li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#byte-sequence">byte sequence</dfn><li>
<li><dfn data-x-href="https://infra.spec.whatwg.org/#string">string</dfn>,
<dfn data-x-href="https://infra.spec.whatwg.org/#code-unit">code unit</dfn>,
<dfn data-x-href="https://infra.spec.whatwg.org/#string-length">length</dfn>, and
Expand Down Expand Up @@ -2487,7 +2488,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#requestcredentials"><code>RequestCredentials</code></dfn> enumeration</li>
noamr marked this conversation as resolved.
Show resolved Hide resolved
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#requestdestination"><code>RequestDestination</code></dfn> enumeration</li>
<li>the <dfn data-x-href="https://fetch.spec.whatwg.org/#dom-global-fetch"><code>fetch()</code></dfn> method</li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#finalize-and-report-timing">finalize and report timing</dfn></li>
<li><dfn data-x="serialize-a-response-url-for-reporting" data-x-href="https://fetch.spec.whatwg.org/#serialize-a-response-url-for-reporting">serialize a response URL for reporting</dfn></li>
<li><dfn data-x="body safely extract" data-x-href="https://fetch.spec.whatwg.org/#bodyinit-safely-extract">safely extracting a body</dfn></li>
<li><dfn data-x-href="https://fetch.spec.whatwg.org/#process-response-end-of-body">processResponseEndOfBody</dfn></li>
<li>
<dfn data-x="concept-response"
data-x-href="https://fetch.spec.whatwg.org/#concept-response">response</dfn> and its
Expand Down Expand Up @@ -13997,37 +14001,14 @@ interface <dfn interface>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
<var>el</var>, is as follows:</p>

<ol>
<li><p>If <var>el</var>'s <code data-x="attr-link-href">href</code> attribute's value is the
empty string, then return.</p></li>
<li><p>Let <var>request</var> be the result of
domenic marked this conversation as resolved.
Show resolved Hide resolved
<span data-x="create a link element request">creating a <code>link</code> element request</span>
given <var>el</var>.</p></li>

<li><p><span>Parse a URL</span> given <var>el</var>'s <code data-x="attr-link-href">href</code>
attribute, relative to <var>el</var>'s <span>node document</span>. If that fails, then return.
Otherwise, let <var>url</var> be the <span>resulting URL record</span>.</p></li>

<li><p>Let <var>corsAttributeState</var> be the current state of <var>el</var>'s <code
data-x="attr-link-crossorigin">crossorigin</code> content attribute.</p></li>

<li><p>Let <var>request</var> be the result of <span
data-x="create a potential-CORS request">creating a potential-CORS request</span> given
<var>url</var>, the empty string, and <var>corsAttributeState</var>.</p></li>
<li><p>If <var>request</var> is null, then return.</p></li>

<li><p>Set <var>request</var>'s <span>synchronous flag</span>.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-client">client</span> to
<var>el</var>'s <span>node document</span>'s <span>relevant settings object</span>.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-nonce-metadata">cryptographic
nonce metadata</span> to the current value of <var>el</var>'s <span>[[CryptographicNonce]]</span>
internal slot.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-integrity-metadata">integrity
metadata</span> to the current value of <var>el</var>'s <code
data-x="attr-link-integrity">integrity</code> content attribute.</p></li>

<li><p>Set <var>request</var>'s
<span data-x="concept-request-referrer-policy">referrer policy</span> to the current state of
<var>el</var>'s <code data-x="attr-link-referrerpolicy">referrerpolicy</code> attribute.</p></li>

<li><p>Run the <span>linked resource fetch setup steps</span>, given <var>el</var> and
<var>request</var>. If the result is false, then return.</p></li>

Expand Down Expand Up @@ -14067,6 +14048,42 @@ interface <dfn interface>HTMLLinkElement</dfn> : <span>HTMLElement</span> {
</li>
</ol>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"To create a link element request given a link element el:"

Also, <code> around link

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still should be "To" instead of "The steps to:"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

<p>To <dfn data-x="create a link element request">create a <code>link</code> element request</dfn>
given a <code>link</code> element <var>el</var> and an optional string <var>destination</var>
(default the empty string):</p>

<ol>
<li><p>If <var>el</var>'s <code data-x="attr-link-href">href</code> attribute's value is the
empty string, then return null.</p></li>

<li><p><span>Parse a URL</span> given <var>el</var>'s <code data-x="attr-link-href">href</code>
attribute, relative to <var>el</var>'s <span>node document</span>. If that fails, then return
null. Otherwise, let <var>url</var> be the <span>resulting URL record</span>.</p></li>

<li><p>Let <var>corsAttributeState</var> be the current state of <var>el</var>'s <code
data-x="attr-link-crossorigin">crossorigin</code> content attribute.</p></li>

<li><p>Let <var>request</var> be the result of <span
domenic marked this conversation as resolved.
Show resolved Hide resolved
data-x="create a potential-CORS request">creating a potential-CORS request</span> given
<var>url</var>, <var>destination</var>, and <var>corsAttributeState</var>.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-client">client</span> to
<var>el</var>'s <span>node document</span>'s <span>relevant settings object</span>.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-nonce-metadata">cryptographic
nonce metadata</span> to the current value of <var>el</var>'s <span>[[CryptographicNonce]]</span>
internal slot.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-integrity-metadata">integrity
metadata</span> to the current value of <var>el</var>'s <code
data-x="attr-link-integrity">integrity</code> content attribute.</p></li>

<li><p>Set <var>request</var>'s
domenic marked this conversation as resolved.
Show resolved Hide resolved
<span data-x="concept-request-referrer-policy">referrer policy</span> to the current state of
<var>el</var>'s <code data-x="attr-link-referrerpolicy">referrerpolicy</code> content
attribute.</p></li>
</ol>
domenic marked this conversation as resolved.
Show resolved Hide resolved

<p>User agents may opt to only try to <span data-x="fetch and process the linked resource">fetch
and process</span> such resources when they are needed, instead of pro-actively fetching all the
<span data-x="external resource link">external resources</span> that are not applied.</p>
Expand Down Expand Up @@ -25415,34 +25432,105 @@ document.body.appendChild(wbr);</code></pre>
elements. This keyword creates an <span data-x="external resource link">external resource
domenic marked this conversation as resolved.
Show resolved Hide resolved
link</span>. This keyword is <span>body-ok</span>.</p>

<p>The <code data-x="rel-preload">preload</code> keyword indicates that the user agent must
<p>The <code data-x="rel-preload">preload</code> keyword indicates that the user agent will
preemptively <span data-x="concept-fetch">fetch</span> and cache the specified resource according
to the <span data-x="concept-potential-destination">potential destination</span> given by the
<code data-x="attr-link-as">as</code> attribute (and the <span
data-x="concept-request-priority">priority</span> associated with the <span
data-x="concept-potential-destination-translate">corresponding</span> <span
noamr marked this conversation as resolved.
Show resolved Hide resolved
data-x="concept-request-destination">destination</span>), as it is highly likely that the user
will require this resource for the current navigation. <span w-nodev>User agents must implement
the processing model of the <code data-x="rel-preload">preload</code> keyword described in
<cite>Preload</cite>, as well as in this specification's <span>fetch and process the linked
resource</span> algorithm.</span> <ref spec=PRELOAD></p>
will require this resource for the current navigation. <ref spec=PRELOAD></p>

<p>There is no default type for resources given by the <code data-x="rel-preload">preload</code>
keyword.</p>

<p>The <span>linked resource fetch setup steps</span> for this type of linked resource, given a
<code>link</code> element <var>el</var> and <span data-x="concept-request">request</span>
<var>request</var>, are:</p>
<p>A <code>Document</code> has a <dfn>map of preloaded resources</dfn>, which is a
domenic marked this conversation as resolved.
Show resolved Hide resolved
<span>map</span>, initially empty.</p>
domenic marked this conversation as resolved.
Show resolved Hide resolved

noamr marked this conversation as resolved.
Show resolved Hide resolved
<p>A <dfn>preload key</dfn> is a <span>struct</span>. It has the following
<span data-x="struct item">items</span>:</p>

domenic marked this conversation as resolved.
Show resolved Hide resolved
<dl>
<dt><dfn data-x="preload URL">URL</dfn>
<dd>A <span>URL</span>
noamr marked this conversation as resolved.
Show resolved Hide resolved

<dt><dfn data-x="preload destination">destination</dfn>
<dt><dfn data-x="preload integrity metadata">integrity metadata</dfn>
<dd>A string

<dt><dfn data-x="preload mode">mode</dfn>
domenic marked this conversation as resolved.
Show resolved Hide resolved
<dd>A <span data-x="concept-request-mode">request mode</span>, either
<code data-x="">same-origin</code>", "<code data-x="">cors</code>", or
"<code data-x="">no-cors</code>"
domenic marked this conversation as resolved.
Show resolved Hide resolved

<dt><dfn data-x="preload credentials mode">credentials mode</dfn>
noamr marked this conversation as resolved.
Show resolved Hide resolved
<dd>A <span data-x="concept-request-credentials-mode">credentials mode</span>
domenic marked this conversation as resolved.
Show resolved Hide resolved
</dl>


<p>A <dfn>preload entry</dfn> is a <span>struct</span>. It has the following
<span data-x="struct item">items</span>:</p>
noamr marked this conversation as resolved.
Show resolved Hide resolved

<dl>
<dt><dfn data-x="preload response">response</dfn>
<dd>Null or a <span data-x="concept-response">response</span>

<dt><dfn data-x="preload on response available">on response available</dfn>
<dd>Null, or an algorithm accepting a <span data-x="concept-response">response</span> or null
</dl>

<p>To <dfn export>consume a preloaded resource</dfn> for <code>Window</code> <var>window</var>,
given a <span>URL</span> <var>url</var>, a string <var>destination</var>, a string
<var>mode</var>, a string <var>credentialsMode</var>, a string <var>integrityMetadata</var>, and
<var>onResponseAvailable</var>, which is an algorithm accepting a
<span data-x="concept-response">response</span>:

<ol>
<li><p>Let <var>key</var> be a <span>preload key</span> whose
domenic marked this conversation as resolved.
Show resolved Hide resolved
<span data-x="preload URL">URL</span> is <var>url</var>,
<span data-x="preload destination">destination</span> is <var>destination</var>,
<span data-x="preload integrity metadata">integrity metadata</span> is
<var>integrityMetadata</var>, <span data-x="preload mode">mode</span> is <var>mode</var>, and
<span data-x="preload credentials mode">credentials mode</span> is
<var>credentialsMode</var>.</p></li>

<li><p>Let <var>preloads</var> be <var>window</var>'s
<span data-x="concept-document-window">associated <code>Document</code></span>'s
<span>map of preloaded resources</span>.</p></li>

<li><p>If <var>key</var> does not <span data-x="map exists">exist</span> in <var>preloads</var>,
then return false.</p></li>

<li><p>Let <var>entry</var> be <var>preloads</var>[<var>key</var>].</p></li>

<li><p><span data-x="map remove">Remove</span> <var>preloads</var>[<var>key</var>].</p></li>
domenic marked this conversation as resolved.
Show resolved Hide resolved

domenic marked this conversation as resolved.
Show resolved Hide resolved
<li><p>If <var>entry</var> <span data-x="preload response">response</span> is null,
then set <var>entry</var>'s
<span data-x="preload on response available">on response available</span> to
<var>onResponseAvailable</var>.</p></li>

domenic marked this conversation as resolved.
Show resolved Hide resolved
<li><p>Otherwise, call <var>onResponseAvailable</var> with <var>entry</var>'s
<span data-x="preload response">response</span>.</p></li>

<li><p>Return true.</p></li>
</ol>

<p>The <span>fetch and process the linked resource</span> steps for this type of linked resource,
given a <code>link</code> element <var>el</var>, are:</p>

<ol>
<li><p>Let <var>as</var> be the current state of <var>el</var>'s <code
data-x="attr-link-as">as</code> attribute.</p></li>

<li><p>If <var>as</var> does not represent a state, return false.</p></li>

<li><p>Set <var>request</var>'s <span data-x="concept-request-destination">destination</span> to
the result of <span data-x="concept-potential-destination-translate">translating</span>
<var>as</var>.</p></li>
<li><p>Let <var>request</var> be the result of
<span data-x="create a link element request">creating a <code>link</code> element request</span>
given <var>el</var> and the result of
<span data-x="concept-potential-destination-translate">translating</span> <var>as</var>.<p></li>

<li><p>If <var>request</var> is null, then return.</p></li>

<li>
<p>If <var>as</var> is "<code data-x="">image</code>", then:</p>
Expand All @@ -25463,7 +25551,65 @@ document.body.appendChild(wbr);</code></pre>
</ol>
</li>

<li><p>Return true.</p></li>
<li><p>Let <var>preloadKey</var> be a <span>preload key</span>
whose <span data-x="preload URL">URL</span> is <var>request</var>'s
<span data-x="concept-request-url">URL</span>,
<span data-x="preload destination">destination</span> is <var>request</var>'s
<span data-x="concept-request-destination">destination</span>,
<span data-x="preload integrity metadata">integrity metadata</span> is <var>request</var>'s
domenic marked this conversation as resolved.
Show resolved Hide resolved
<span data-x="concept-request-integrity-metadata">integrity metadata</span>,
<span data-x="preload mode">mode</span> is <var>request</var>'s
<span data-x="concept-request-mode">mode</span>, and
<span data-x="preload credentials mode">credentials mode</span> is <var>request</var>'s
<span data-x="concept-request-credentials-mode">credentials mode</span>.</p></li>

domenic marked this conversation as resolved.
Show resolved Hide resolved
<li><p>Let <var>preloadEntry</var> be a new <span>preload entry</span>.</p></li>

domenic marked this conversation as resolved.
Show resolved Hide resolved
<li><p><span data-x="map set">Set</span> <var>el</var>'s <span>node document</span>'s
<span>map of preloaded resources</span>[<var>preloadKey</var>] to
<var>preloadEntry</var>.</p></li>
domenic marked this conversation as resolved.
Show resolved Hide resolved

<li>
<p><span data-x="concept-fetch">Fetch</span> <var>request</var>, with
<i data-x="processResponseEndOfBody">processResponseEndOfBody</i> set to the following steps
given <span data-x="concept-response">response</span> <var>response</var> and
domenic marked this conversation as resolved.
Show resolved Hide resolved
null or <span>byte sequence</span> <var>bytesOrNull</var>:</p>

domenic marked this conversation as resolved.
Show resolved Hide resolved
<ol>
<li>
<p>If <var>bytesOrNull</var> is a <span>byte sequence</span>, then set
<var>response</var>'s <span data-x="concept-response-body">body</span> to the
first return value of <span data-x="body safely extract">safely extracting</span>
<var>bytesOrNull</var>.</p>

<p class=note>By using <i data-x="processResponseEndOfBody">processResponseEndOfBody</i>,
we have <span data-x="body safely extract">extracted</span> the entire
<span data-x="concept-response-body">body</span>. This is necessary to ensure the preloader
domenic marked this conversation as resolved.
Show resolved Hide resolved
loads the entire body from the network, regardless of whether the preload will be consumed
(which is uncertain at this point). This step then resets the request's body to a new body
containing the same bytes, so that other specifications can read from it at the time of actual
domenic marked this conversation as resolved.
Show resolved Hide resolved
consumption, despite us having already done so once.</p>
domenic marked this conversation as resolved.
Show resolved Hide resolved
</li>

<li><p>Otherwise, set <var>response</var> to a <span>network error</span>.</p></li>
domenic marked this conversation as resolved.
Show resolved Hide resolved

<li><p><span>Finalize and report timing</span> with <var>response</var>,
given <var>el</var>'s <span>relevant global object</span> and
domenic marked this conversation as resolved.
Show resolved Hide resolved
"<code data-x="">link</code>".</p></li>

<li><p><span data-x="concept-event-fire">Fire an event</span> named
<code data-x="event-load">load</code> at <var>el</var>.</p></li>

<li><p>If <var>preloadEntry</var>'s
<span data-x="preload on response available">on response available</span> is null, then
set <var>preloadEntry</var>'s <span data-x="preload response">response</span> to
<var>response</var>.</p></li>

<li><p>Otherwise, call <var>preloadEntry</var>'s
<span data-x="preload on response available">on response available</span> with
<var>response</var>.</p></li>
</ol>
</li>
</ol>


Expand Down