standards-positions icon indicating copy to clipboard operation
standards-positions copied to clipboard

Navigational prefetching and prerendering

Open domenic opened this issue 2 years ago • 11 comments

Request for position on an emerging web specification

  • WebKittens who can provide input: unsure, maybe @annevk

Information about the spec

  • Spec Title: Prefetch / Prerendering Revamped / Speculation Rules
  • Spec URL: https://wicg.github.io/nav-speculation/prefetch.html
    • https://wicg.github.io/nav-speculation/prerendering.html
    • https://wicg.github.io/nav-speculation/speculation-rules.html
  • GitHub repository: https://github.com/WICG/nav-speculation

Design reviews and vendor positions

  • TAG Design Review: https://github.com/w3ctag/design-reviews/issues/721
  • Mozilla standards-positions issue: https://github.com/mozilla/standards-positions/issues/620

Also https://github.com/mozilla/standards-positions/issues/613.

Bugs tracking this feature

None yet

Anything else we need to know

The Chrome team has been working for the last year or so on creating rigorous specifications for prefetching and prerendering (collectively, "preloading") of navigations. Of particular note, we're:

  • Trying to specify user-agent-initiated prefetching and prerendering, e.g. from the URL bar, so that behavior is uniform (such as, audio will not play while prerendering) and pages have ways of detecting and responding to these preloads.

  • Specifying a new way for web pages to trigger preloads, via the <script type=speculationrules> script block.

  • Paying close attention to respecting the work on storage partitioning. Right now we have specified same- and cross-site prefetch, and same-site prerender; we have some speculative explainers for cross-site prerender.

I chose to file this as an umbrella issue, since all three specs are related and we're specifically trying to make them cohesive, but would be happy to split it if that's preferred.

I believe we've previously asked about this in threads such as https://lists.webkit.org/pipermail/webkit-dev/2022-February/032113.html and https://lists.webkit.org/pipermail/webkit-dev/2022-March/032158.html , without response. (But I'm not 100% sure on that, since right now those pages are giving 403s.) The proximate occasion of me filing this is because Chrome is looking to expand what we ship slightly, by starting to allow same-site cross-origin prerenders. But I saw that as a good opportunity to port the discussion to your shiny new GitHub repository :slightly_smiling_face:.

All of this work is being done as monkey-patch specs for now, but the eventual destination is to integrate with HTML and Fetch. (Plus many other affected specs, for prerendering.) We've also been discussing this work periodically with the W3C Web Perf Working Group. We are particularly optimistic about upstreaming enough of the specs to support user-agent initiated preloading, since we believe WebKit already performs such preloading. We hope to work on that after https://github.com/whatwg/html/pull/6315 lands.

domenic avatar Sep 02 '22 05:09 domenic

Is there a pointer to specifically what is proposed for cross-site prefetch? Same-origin and same-site cross-origin do not seem to create the same risk of cross-site tracking if loaded with state access, or conversely the risk of fetching/prerendering the wrong content if loaded partitioned to the initiating page, so curious how this issue will be resolved. This is currently our one blocker for <link rel=preload> (a feature with an arguably related purpose).

othermaciej avatar Sep 25 '22 19:09 othermaciej

Cross-site prefetching has this explainer. The specification entry point that is probably most helpful is the main prefetch algorithm, which has a helpful summary note after it.

To summarize the general strategy:

  • If the cross-site destination has any credentials, we currently cancel the prefetch process. (In the spec: "uncredentialed prefetch" step 19.)
  • In the future, we'd like to allow cross-site destinations with credentials to opt in to being prefetched with no credentials. (This opt-in is required because unaware sites would do things like delivering the logged-out HTML, which would give a bad user experience.)
  • In either case, any credentials or HTTP cache updates are done in an isolated partition. If the prefetch is activated, this partition's contents gets merged into the non-isolated partition for the destination site.

This is currently our one blocker for <link rel=preload> (a feature with an arguably related purpose).

I think <link rel=preload> is simpler since its cache is specced to be per-document, and so it doesn't need to survive navigations. It can just use the same cross-site partitioning everyone is already using for subresources.

domenic avatar Sep 26 '22 01:09 domenic

Hello. We have an extension to the speculation rules syntax to allow the referrer policy of a speculative request to be set explicitly. A key use case for this is to allow a site with a lax referrer policy to adopt cross-site prefetching by using a strict policy specifically for the prefetch.

Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#explicit-referrer-policy Spec: https://wicg.github.io/nav-speculation/speculation-rules.html

(Note that as of this writing, the most recent version of the spec hasn't yet been published at that link, but should be available soon.)

Please take a look.

kjmcnee avatar Dec 09 '22 21:12 kjmcnee

Just dropping a note here to mention that Chrome is planning an experiment with an expanded subset of this feature soon, notably including document rules, an HTTP response header as an alternative to using an inline <script>, and integration with a proposed PerformanceResourceTiming.deliveryType to enable authors to determine whether the navigation was served from the prefetch cache.

Thanks!

jeremyroman avatar Dec 16 '22 02:12 jeremyroman

Hi. We have delta updates on how the speculation rules should interact with Content Security Policy.

Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#content-security-policy

We added Content Security Policy section to clarify how the speculation rules interact with existing Content Security Policy, and explain the new source keyword "inline-speculation-rules".

We also added Content Security Policy section to the speculation rules spec, in order to explain the motivation and to show spec patches for Content Security Policy. Spec (diff): https://storage.googleapis.com/spec-previews/WICG/nav-speculation/pull/245/diff/speculation-rules.html

In short, we clarify how the speculation rules are handled in CSP, and provide a new source keyword to permit safe inline speculation rules without allowing unsafe inline script under the strict CSP environment. Here is an example use.

<meta http-equiv="Content-Security-Policy" content="script-src 'inline-speculation-rules'">

<!-- this just works!! -->
<script type="speculationrules">
...
</script>

<!-- this causes a CSP violation -->
<script>
console.log('hello.');
</script>

toyoshim avatar Mar 09 '23 06:03 toyoshim

In the future, we'd like to allow cross-site destinations with credentials to opt in to being prefetched with no credentials. (This opt-in is required because unaware sites would do things like delivering the logged-out HTML, which would give a bad user experience.)

Will the opt-in also cover IP address protection so that sites that opt in promise to respond with the requested content even if the client is hiding its IP address?

johnwilander avatar Apr 20 '23 05:04 johnwilander

Will the opt-in also cover IP address protection so that sites that opt in promise to respond with the requested content even if the client is hiding its IP address?

That's a very interesting idea! We hadn't really considered sites needing to opt in to that; our limited experience using IP address protection proxies (see here) has just applied them when the referrer site requested, without requiring the destination site to opt-in.

But, I think it would be a pretty natural extension of Supports-Loading-Mode: uncredentialed-prefetch to also imply the semantics you suggest.

To make sure I'm understanding, this wouldn't involve changing any browser code, but instead would be about the documentation around that header, right?

domenic avatar Apr 24 '23 05:04 domenic

I tend to agree with @domenic, though there is no technical mechanism for enforcing this "promise". I expect that, like today, some sites will still geotarget content at least coarsely (hopefully coarsely enough that changes to a different network or IP-anonymizing proxy that isn't trying to conceal the user's jurisdiction altogether doesn't cause significant disruption).

By way of comparison, any resource which is cacheable at all currently implies (perhaps falsely) that it's invariant to IP address, because devices can change IP address these days (by enabling a proxy, by switching to a mobile network, by going to a coffee shop) and I don't think anything forces them to invalidate the cache when they do so (though perhaps some user agent does).

If you tilt your head, IP address looks kinda like a credential anyway (except that it's wrapped around the HTTP data on the wire, rather than inside it).

jeremyroman avatar Apr 24 '23 18:04 jeremyroman

While I haven't looked at all aspects

Trying to specify user-agent-initiated prefetching and prerendering, e.g. from the URL bar, so that behavior is uniform (such as, audio will not play while prerendering) and pages have ways of detecting and responding to these preloads.

seems quite agreeable. Whether we need to give pages a way of detecting a prerender would be nice to flush out a bit more. Perhaps the fact that their visibility state is hidden from the start covers a lot of these scenarios? I realize that currently specifications are bad at accounting for visibility, but that would have to be cleaned up either way.

annevk avatar Apr 26 '23 09:04 annevk

Hello. We have an extension to the speculation rules syntax to explicitly set a No-Vary-Search hint on a speculative request. The hint is useful because prefetches that depend on No-Vary-Search header to match to navigations do not benefit the user if the navigation happens before prefetch headers return from the server. Using the hint, the web browser will wait for a matching in-flight prefetch and will expect, but verify, that the No-Vary-Search hint matches the No-Vary-Search header. If the No-Vary-Search hint does not match the No-Vary-Search header received then the web browser will send a new request to the server.

Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#no-vary-search-hint Spec: https://wicg.github.io/nav-speculation/speculation-rules.html No-Vary-Search header request for position: https://github.com/WebKit/standards-positions/issues/106

(Note that as of this writing, the most recent version of the spec hasn't yet been published at that link, but should be available soon.) Please take a look.

liviutinta avatar Jun 26 '23 20:06 liviutinta

Hi, we're expanding the syntax for speculation rules to allow developers to specify the target_hint field.

This field provides a hint to indicate a target navigable where a prerendered page will eventually be activated. For example, when _blank is specified as a hint, a prerendered page can be activated for a navigable opened by window.open(). The field has no effect on prefetching.

<script type=speculationrules>
{
  "prerender": [{
    "target_hint": "_blank",
    "urls": ["page.html"]
  }]
}
</script>
<a target="_blank" href="page.html">click me</a>

Please see the explainer for the motivation of this extension.

Explainer: https://github.com/WICG/nav-speculation/blob/main/triggers.md#window-name-targeting-hints Spec: https://wicg.github.io/nav-speculation/speculation-rules.html Chrome platform status: https://chromestatus.com/feature/5162540351094784

nhiroki avatar Jan 19 '24 16:01 nhiroki