Skip to content
This repository has been archived by the owner on Jun 30, 2023. It is now read-only.

Prefetch vs Service Workers #78

Closed
jyasskin opened this issue Apr 4, 2018 · 8 comments
Closed

Prefetch vs Service Workers #78

jyasskin opened this issue Apr 4, 2018 · 8 comments
Assignees

Comments

@jyasskin
Copy link
Member

jyasskin commented Apr 4, 2018

In a recent discussion, it was pointed out that if page A includes <link rel=prefetch href=B> and <link rel=prefetch href=C>, both B and C are requested through A's Service Worker. It would be possible to force either to go through its own SW using an as=document attribute, but that's unimplemented and likely being removed (#66).

If the user winds up clicking a link to B, which uses C as a subresource, the real subresource request for C goes through B's SW, which A's <link rel=prefetch href=C> can't achieve either with or without the as attribute.

I can imagine several options:

  1. Give <link rel=prefetch> a new attribute explicitly saying which SW to send the request through. However, I could imagine some SWs breaking if any attacker could send them a fetch their site would never actually send.
  2. Assume all prefetches are for the top-level resource of a navigation, and send them through the href's service worker.
  3. Say that <link rel=prefetch> is only for pre-populating the HTTP and preload caches and should always skip the SW layer. Then a site with an <a href=D> might have to <link rel=prefetch> something other than D if D's Service Worker is going to build its response for D from several non-D subresources.

I don't see the current behavior of going through the referrer's SW as a sensible option now that we've thought about it, but maybe I've just missed something, and I could imagine that we're stuck here now.

What do folks think?

@wanderview
Copy link
Member

Triggering a cross-origin service worker based on a element seems a bit like foreign fetch to me in terms of enabling tracking cookies. If it was limited to something like "as=document", then the browser could treat them like iframes and respect the user's configured 3rd party iframe policies.

@jyasskin
Copy link
Member Author

Ah, trackers, ruining things for everyone. Thanks for pointing out that angle.

For browsers with third-party cookies turned off, I think the mitigation for (2) and (1) is the same: either block the prefetch or fall back to (3). It's possible we could come up with a declarative or Worklet-based system to let the third-party SW map request URLs to the set of resources needed to serve them, without being able to record anything as a result, but that's more complex than I'd want to design without some more concrete use cases.

@yoavweiss
Copy link
Contributor

If there's a concrete use-case for as=document, it can be easily implemented and remain in the spec.
It makes sense for navigation prefetches to go through the destination SW.

However, I'm wondering if we should define a "prefetch cache" below the SW, where prefetch requests would bypass the current SW entirely, and will go through SW only once the resource is used (by the future Document).

@wanderview
Copy link
Member

If there's a concrete use-case for as=document, it can be easily implemented and remain in the spec.
It makes sense for navigation prefetches to go through the destination SW.

Keep in mind that for privacy reasons this would have to be treated as a non-top level navigation. So things like 3rd party storage blocking and such would have to be applied. Webkit would probably want to partition any service worker interception a prefetch like this as if it was a 3rd party frame.

If the developer is using the document prefetch to prime possible navigations beyond the current page, is this really useful?

However, I'm wondering if we should define a "prefetch cache" below the SW, where prefetch requests would bypass the current SW entirely, and will go through SW only once the resource is used (by the future Document).

Where does it say to consult the prefetch cache? If it was tied to the request's internal client value then in theory we could allow passthrough evt.respondWith(fetch(evt.request)) consult the prefetch cache.

Of course implementation would have to deal with the client and service worker threads living in different processes.

@horo-t
Copy link
Member

horo-t commented Mar 19, 2019

We are discussing about signed exchange prefetching at WICG/webpackage#347 (comment).
But I think we should discuss about the interaction of prefetching and service workeres here.

The idea is:
If the resource (both main and subresources) is prefetched in the previous page, expose the prefetched response in the service worker as FetchEvent.preloadResponse.

@yoavweiss
Copy link
Contributor

To be defined as part of #86

/cc @noamr

@noamr
Copy link
Contributor

noamr commented Apr 10, 2022

So, to reiterate what I understand from this, the issue is that same-origin documents might not have the same SW, which means that a prefetch from the first would be lost by the second?

#86 does make this explicit, we have to see whether the prefetch cache is similar to the preload cache, which is "above" service-workers, or to the HTTP cache, which is "below" service workers.

This issue is perhaps a use-case that shows an advantage to the former.

@noamr
Copy link
Contributor

noamr commented Mar 27, 2023

This is well defined now

@noamr noamr closed this as completed Mar 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants