-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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 link processing for prefetch #8111
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is certainly simple; I have no qualms with the algorithm. However:
Already implemented
seems unlikely? My understanding is there's a lot of non-interop on prefetch from various implementers, and nobody currently implements this proposal exactly. Or maybe Firefox does, and that's why they're N/A for the bug link?
The Safari bug seems to be about something that isn't captured in this spec proposal. If we don't want to allow prefetch during loading, that should be normatively enforced.
The Chrome bug seems to be about removing the 5-minute rule, but are there more things Chrome does, e.g. use a memory cache, special treatment of other headers besides max-age, etc. which also need bugs?
source
Outdated
</ol> | ||
|
||
<p>The <span>process a link header</span> steps for this type of linked resource are to do | ||
nothing.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit surprising to me. Tests would be good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working on it :)
source
Outdated
to "<code data-x="">prefetch</code>".</p></li> | ||
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-initiator">initiator</span> | ||
to "<code data-x="">prefetch</code>".</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we modify https://fetch.spec.whatwg.org/#concept-request-priority somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. It's still implementation-defined.
source
Outdated
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-initiator">initiator</span> | ||
to "<code data-x="">prefetch</code>".</p></li> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As noted in #5229 I guess we should add some headers? But which ones? See https://wicg.github.io/nav-speculation/prefetch.html#prefetch-algorithms step 5 for what nav-speculation is doing. It includes a carveout for vendor-specific headers which I dislike but decided was OK back in WICG/nav-speculation#133 (comment) .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already send Purpose: Prefetch
. I think we should also send Sec-Purpose: Prefetch
and have it as part of the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we allow/encourage/require Purpose: Prefetch
? What about X-moz: prefetch
or X-Purpose: preview
? Those latter two values were tested, I think, for things besides <link rel="prefetch">
; do you know what Firefox and Safari do for <link rel="prefetch">
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think currently we're specifying as Sec-Purpose: Prefetch, and everything else is proprietary and UAs will probably keep it for backwards compat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hope they plan on removing the non-compliant headers. If the plan is that everyone ends up with multiple incompatible headers that does not seem great and at that point there's no real value in using Sec-
either, right?
Actually Safari implements this exactly. Firefox have an intricate way to de-prioritize prefetches, i.e. performing them one by one and only after the window onload event is fired. I wonder if this needs to be interoperable, or if this can be considered as their implementation of determining request priority.
I referenced this bug because the bug mentions that prefetch is not entirely spec'ed yet.
From what I understood, the special treatment is for navigations, which would be ported to nav-speculation in due time. But I'll double check. Regarding using the memory cache, it feels more of an optimization, I'm not sure it's observable in any way. |
OK, so they should probably wontfix https://bugs.webkit.org/show_bug.cgi?id=49238 then?
It feels like a bit of a stretch, but, maybe it's OK, given how vague priority is. My main concern is that if there are patterns that browsers should follow to conform to websites' expectations and usage, then we should try to encode that, so that browsers implementing the spec naively don't end up causing sites to perform poorly in their browser. It's not clear to me whether or not that's the case.
My understanding was that the memory cache prevents future fetches from hitting the network and/or service worker, which would otherwise do so. I might be wrong. Also a crbug comment from 2013 indicates that whether or not |
I think they should consider how they implement fetching priority if it bothers their users. But perhaps it's not a spec concern.
I agree with that. I wonder if this can be done incrementally.
Right, so a test can be written that checks if consuming a disk-cachable prefetch has hit a service worker. Will give it a go.
I believe it should definitely not block the load events. In Firefox it wouldn't even take place before the load event. I will check what WPTs tell us. |
I checked this. The prefetch cache in chrome is actually some special consideration about when to invalidate, but it's really the regular disk cache. It doesn't prevent SWs from running again on the same resource. |
#5229 (comment) discusses even more departures that Chrome has from this proposed spec: some special behavior for as=document that allows it to be used to speed up cross-site navigations. I am a bit frustrated that was not mentioned either in the implementer support section. Are we planning to remove that in Chrome? If not then I think it would be bad to move forward with this spec proposal which specifies something so different... |
Yes, the idea as I understood it was to move the as=document things to nav-speculation. I didn't mention it because I wanted to specify the common-denominator first, and then discuss the "chrome only" bits and see what of it needs to stay in . What frustrates me is that it's terribly difficult to get people to join this conversation over something that's implemented differently in each browser and not specified... Could use some help with that. |
Well, it seems like we might have a good basis? If Safari matches this PR, and Firefox maybe matches it except for some stuff about load timing which we think is OK, then Chrome is the odd one out, right? We don't really need that much of a conversation; we just need Chrome to commit to matching the other two browsers. To be clear, I don't think interpreting Chrome's current implementation as a superset of this PR is a great application of the WHATWG working mode. "Yes, we implement this PR but also a bunch of other stuff triggered by the same link rel" would justify a lot of weirdness, if we extended that rule more broadly. We could just merge this on the basis of Firefox + Safari support, saying we don't know Chrome's position on it, but (a) that's a weird thing for two Chrome engineers to conclude 🙂 and (b) if there's a chance that Chrome wants to actually steer the semantics of rel=prefetch toward something other than what's in this PR in the future, then it feels like this PR is a bit deceptive, especially for Firefox + Safari engineers who might think it indicates an agreement on a specific behavior, when in reality it doesn't. |
Update: restrictive prefetch ( |
That sounds good. Here are some things we should be sure to test:
Once we have those test results, we can know exactly how far everyone is from the proposal, and confirm that everyone is on board with making the necessary changes. |
https://bugs.chromium.org/p/chromium/issues/detail?id=1357407 |
I dug deep into I propose the following:
|
In spec land, I think this is the same as when fetching with (To be clear, we don't need to solve that entire issue before proceeding here, but I want to get a sense of what the intent is, and maybe encode it in the spec and tests if we can do so despite the shaky foundations.)
(Assuming you mean "Consuming a prefetch" just means "making a fetch", right? A fetch that will hit the HTTP cache that the prefetch might have populated? I'm not sure it's a good idea to start selectively ignoring If there is significant evidence of |
Not sure yet, still investigating. It needs to tell the server which mime types the user agent supports and do some intricate content negotation thingies like SXG quality, and OTOH be ignored by the client HTTP cache.
Yes, of course :)
Yes.
Well it's a subset of Chromium's current "5 minute rule" for prefetches, which would be the precedent. I think the alternative to doing this would be to deprecate |
See whatwg/html#8111 (comment) Tests that: * preload/prefetch-cache.html No 5 minute rule (cache headers must be respected) * preload/prefetch-document.html No special treatment of as=document Whether Accept is left as its default value. Storage partitioning is applied, including for documents * preload/prefetch-load-event.html Does not block the load event * preload/prefetch-headers.html Whether any additional headers (Sec-Purpose, Purpose, X-moz, X-Purpose) are sent (depending on what we put in the spec) * preload/prefetch-types.html Always uses prefetch destination, and ignores as=""
Done.
Updated the OP. Still need to figure out if what we do here with |
When people use a library to prefetch HTML (which allows speeding one’s website very easily), like my library instant.page, or quicklink/Flying Pages/etc., they expect it to just work and generally don’t know jack about caching headers. Even if they know they don’t have those conflicts in their head. Caching conflicts with prefetch are always a bad surprise in general. In the wild, Shopify uses Vary: Accept, causing problems. That’s a lot of sites where people just can’t set “correct” caching headers to let prefetch do its magic. I think standardizing ignoring Vary: Accept would be a great way to ensure in the long term that various changes to browsers' Accept headers don’t make a collateral damage of prefetch. |
It's actually the same as when fetching a document (iframe/window.open etc). You can prefetch anything that your browser can load. So I suggest to add Looking at whatwg/fetch#274 that switch statement is anyway far from useful, but understanding now that |
@emilio @sefeng211 @bdekoz: Gecko thoughts? Trying to make prefetch interoperability less insane so please pitch in :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking pretty solid, assuming we can get cross-browser agreement... the test results are somewhat grim though! https://github.com/web-platform-tests/wpt/pull/35707/checks?check_run_id=8191297010
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as I understand it this essentially makes prefetch
a way to fill the HTTP cache, with some special request headers and optionally some priority adjustments.
(This means that service workers will still be consulted.)
Chatting with colleagues that seems like an acceptable model.
source
Outdated
link request</span> given <var>options</var>.</p></li> | ||
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-initiator">initiator</span> to | ||
"<code data-x="">prefetch</code>"..</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two dots at the end here seems wrong?
A detailed output: Prefetch is predominantly used for same-origin scripts (57%) and same-origin CSS (18%). My take on this data is that prefetch used to be a search-engine feature, and today it's more of a landing-page feature (you serve a very lean and fast landing page that prefetches the scripts & styles of the complex main page/web-app) |
The purpose headers allows servers to discern between regular requests and "resource hints" - requests that are only meant to populate caches. This replaces the existing `Purpose` and `x-moz: prefetch` headers. Closes w3c/webappsec-fetch-metadata#84 Part of whatwg/html#8111
Done in whatwg/fetch#1576 |
The purpose headers allows servers to discern between regular requests and "resource hints" - requests that are only meant to populate caches. This replaces the existing `Purpose` and `x-moz: prefetch` headers. Closes w3c/webappsec-fetch-metadata#84 Part of whatwg/html#8111
Prefetch is simply a fetch with `prefetch-src` CSP and no post-processing of the resource. Closes whatwg#5229
See whatwg/html#8111 (comment) Tests that: * preload/prefetch-cache.html No 5 minute rule (cache headers must be respected) * preload/prefetch-document.html No special treatment of as=document Whether Accept is left as its default value. Storage partitioning is applied, including for documents * preload/prefetch-load-event.html Does not block the load event * preload/prefetch-headers.html Whether any additional headers (Sec-Purpose, Purpose, X-moz, X-Purpose) are sent (depending on what we put in the spec) * preload/prefetch-types.html Always uses prefetch destination, and ignores as=""
This replaces the existing `Purpose: prefetch` and `x-moz: prefetch` headers. Tests: web-platform-tests/wpt#35707. Part of whatwg/html#8111. Closes w3c/webappsec-fetch-metadata#84 and w3c/resource-hints#74. Co-authored-by: Anne van Kesteren <annevk@annevk.nl>
Complements whatwg/html#8111. Co-authored-by: Anne van Kesteren <annevk@annevk.nl>
See whatwg/html#8111 (comment) Tests that: * preload/prefetch-cache.html No 5 minute rule (cache headers must be respected) * preload/prefetch-document.html No special treatment of as=document Whether Accept is left as its default value. Storage partitioning is applied, including for documents * preload/prefetch-load-event.html Does not block the load event * preload/prefetch-headers.html Whether any additional headers (Sec-Purpose, Purpose, X-moz, X-Purpose) are sent (depending on what we put in the spec) * preload/prefetch-types.html Always uses prefetch destination, and ignores as=""
…, a=testonly Automatic update from web-platform-tests Add multiple tests for prefetch behavior See whatwg/html#8111 (comment) Tests that: * preload/prefetch-cache.html No 5 minute rule (cache headers must be respected) * preload/prefetch-document.html No special treatment of as=document Whether Accept is left as its default value. Storage partitioning is applied, including for documents * preload/prefetch-load-event.html Does not block the load event * preload/prefetch-headers.html Whether any additional headers (Sec-Purpose, Purpose, X-moz, X-Purpose) are sent (depending on what we put in the spec) * preload/prefetch-types.html Always uses prefetch destination, and ignores as="" -- Add tests for load/error events -- Add cross-origin event tests -- Test for proprietary headers -- Add test cases for cross-origin error events -- Update preload/prefetch-cache.html Co-authored-by: Domenic Denicola <d@domenic.me> -- Fix CR comments -- Clean up doc test -- Retries in cache test -- Use script instead of fetch to de-flake firefox -- wpt-commits: 56746bfcf1b8eae23f81f69c144d54bb7441b9c6, 9e12c604be29a47a730ecdb3c1382e678eb9eca4, a221f4091d67ca56f9218929ab019b4b9c2f2302, 5fe9b213f64e80cddb5de0aa8debec29f5ab20ad, 67113e16693e30945f2d2b71a8a4b3f556fe4353, c03154bde9e293f82a631b80f841908c25927493, 18faf32573d6d83c1932167e23bb8f6c37df3eb1, 8f2af79a66aeaece84373ce5e24023edb2c55f08, 8ae300754a3dd226cd58b3fd53e270cf141c28fc, 1423a3236683cc4856158c54e9f8f29eef3d2871 wpt-pr: 35707
…, a=testonly Automatic update from web-platform-tests Add multiple tests for prefetch behavior See whatwg/html#8111 (comment) Tests that: * preload/prefetch-cache.html No 5 minute rule (cache headers must be respected) * preload/prefetch-document.html No special treatment of as=document Whether Accept is left as its default value. Storage partitioning is applied, including for documents * preload/prefetch-load-event.html Does not block the load event * preload/prefetch-headers.html Whether any additional headers (Sec-Purpose, Purpose, X-moz, X-Purpose) are sent (depending on what we put in the spec) * preload/prefetch-types.html Always uses prefetch destination, and ignores as="" -- Add tests for load/error events -- Add cross-origin event tests -- Test for proprietary headers -- Add test cases for cross-origin error events -- Update preload/prefetch-cache.html Co-authored-by: Domenic Denicola <d@domenic.me> -- Fix CR comments -- Clean up doc test -- Retries in cache test -- Use script instead of fetch to de-flake firefox -- wpt-commits: 56746bfcf1b8eae23f81f69c144d54bb7441b9c6, 9e12c604be29a47a730ecdb3c1382e678eb9eca4, a221f4091d67ca56f9218929ab019b4b9c2f2302, 5fe9b213f64e80cddb5de0aa8debec29f5ab20ad, 67113e16693e30945f2d2b71a8a4b3f556fe4353, c03154bde9e293f82a631b80f841908c25927493, 18faf32573d6d83c1932167e23bb8f6c37df3eb1, 8f2af79a66aeaece84373ce5e24023edb2c55f08, 8ae300754a3dd226cd58b3fd53e270cf141c28fc, 1423a3236683cc4856158c54e9f8f29eef3d2871 wpt-pr: 35707
Prefetch is simply a fetch without post-processing the resource, and with a special header:
Sec-Purpose: Prefetch
, which would be added in the Fetch-Metadata spec. See that issue for use-cases for the special header.Closes #5229
Closes w3c/resource-hints#86
Closes w3c/resource-hints#74
Closes whatwg/fetch#1008
At least two implementers are interested (and none opposed):
Sec-Purpose: Header
Tests are written and can be reviewed and commented upon at:
prefetch-src
is already testedImplementation bugs are filed:
1345207: remove the five minute rule
1358419:
Sec-Purpose
header626081: issues with
Accept
801561: Prefetch src
1352371: Remove as=document special treatment
1457204: CSP prefetch-src
1788167: Align prefetch with spec
(See WHATWG Working Mode: Changes for more details.)
/infrastructure.html ( diff )
/links.html ( diff )