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

Prefetch response cloning and reserved clients #346

Open
domenic opened this issue Dec 2, 2024 · 0 comments
Open

Prefetch response cloning and reserved clients #346

domenic opened this issue Dec 2, 2024 · 0 comments

Comments

@domenic
Copy link
Collaborator

domenic commented Dec 2, 2024

@hiroshige-g kindly explained to me some issues with the current spec, which are becoming apparent now that Chromium is working on implementing service worker integration.

The issue stems from the fact that we keep responses in the prefetch records, and then allow reuse of them (as of 5d5ebce) using this line:

Optionally, set response to a clone of response.

in create navigation params from a prefetch record

The problem is that we didn't clone all the relevant state. In particular, the "reserved client", which roughly represents the destination Window/Document the navigation request is going to be used for.

This leads to the following problematic situation. Let's say /A prefetches /B. The user navigates to /B, but document A (and its prefetch cache) stays in bfcache. The user navigates back to /A, restoring from bfcache. Then the user navigates to /B again. Assume our implementation is the sort that allows reuse in the prefetch cache, so it's reusing the same prefetch record for both navigations to /B.

Then what happens is:

  • The FetchEvent's resultingClientId for the original prefetch is id1
    • What happens if the web developer calls clients.get(id1) at this point? There's no actual Window represented by id1, so this doesn't make much sense...
  • The FetchEvent's resultingClientId for the first navigation to /B is id1
    • After this navigation, now clients.get(id1) kind of makes sense.
  • The FetchEvent's resultingClientId for the second navigation to /B is id1
    • But now what does clients.get(id1) mean? Did two separate Windows share a client ID?!

What we should do instead, is expose the empty string to the prefetch FetchEvent (similar to what is done for <link rel=prefetch>), and then expose separate id1 and id2s for the navigation FetchEvents.

To accomplish this, we suggest the strategy that:

  • The navigation param's reserved environment always be set to a clone of the request's reserved client, with the clone updated to have a new ID.
  • The resultingClientId value (set here) is masked to the empty string for the prefetch requests, either by detecting that it's a prefetch request, or by marking the original non-clone reserved client in some special way that the service worker spec can detect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant