WebKit / standards-positions

WebKit's positions on emerging web specifications
https://webkit.org/standards-positions/
240 stars 18 forks source link

Navigational prefetching and prerendering #54

Open domenic opened 1 year ago

domenic commented 1 year ago

Request for position on an emerging web specification

Information about the spec

Design reviews and vendor positions

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:

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.

othermaciej commented 1 year ago

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).

domenic commented 1 year ago

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:

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.

kjmcnee commented 1 year ago

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.

jeremyroman commented 1 year ago

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!

toyoshim commented 1 year ago

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>
johnwilander commented 1 year ago

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?

domenic commented 1 year ago

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?

jeremyroman commented 1 year ago

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).

annevk commented 1 year ago

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.

liviutinta commented 1 year ago

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.

nhiroki commented 5 months ago

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