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

Should the load or error event fire if a link prefetch is canceled? #62

Closed
bzbarsky opened this issue Jul 29, 2016 · 10 comments
Closed

Comments

@bzbarsky
Copy link

This came up when implementing firing of load/error events on <link rel="prefetch"> in Firefox. If the response comes back uncacheable, we cancel the prefetch. Should that fire the load or error event? The spec doesn't have a useful processing model description that would answer this question....

@igrigorik

@yoavweiss
Copy link
Contributor

I believe that in Chrome, non-cacheable prefetch responses are still fetched and cached for a short period. We should probably define the right behavior here, as this can cause compat issues.

@bzbarsky
Copy link
Author

bzbarsky commented Aug 1, 2016

Um... I really don't think we want prefetch to violate HTTP semantics. But yes, we certainly need to define behavior here, so browsers can actually be interoperable.

In the meantime, Firefox will fire error if we cancel due to uncachability, I believe.

@igrigorik
Copy link
Member

@bzbarsky I don't think we're violating HTTP semantics as much as we're navigating uncharted (unspecified) waters.. which is something we definitely need to address. In fact, this very topic came up at the HTTP workshop last week. The rough shape of the problem is as follows:

  • A server can push a resource to the client, which is then matched against a client-initiated request. The pushed resource can be a no-cache resource and it is never committed to HTTP cache, but the pushed response is held (in some other magical cache that we haven't defined but exists in every implementation) by the client until that fetch group goes away (e.g. client navigates to another page).
  • Preload'ed responses have similar behavior as above - e.g. you can preload a no-cache resource and match it without incurring double requests; although unlike push if the resource is cacheable it does also get committed to the HTTP cache when the response is received.
  • Prefetch responses are similar to preload but, to be useful, need to persist across navigations and thus can't be attached to fetch group.. e.g. a click on a link initiates load for critical CSS on that page.
  • Prerender is yet another but more complicated instance..

In short, there is a magical cache here that is not specced and we should probably spend some time on trying to figure out how to unearth that and stick into Fetch, probably? /cc @annevk

Last but not least.. I don't think Firefox should discard and error non-cacheable resources. That said, I think this behavior will fall out once we spec this non-HTTP cache we all have.. :)

@bzbarsky
Copy link
Author

bzbarsky commented Aug 1, 2016

A server can push a resource to the client

We're talking HTTP/2 here, right, not 1.1?

Preload'ed responses have similar behavior as above

Not in Gecko. Gecko treats "preload" as a synonym for "prefetch", fwiw. Both just prime the normal HTTP cache, with no other magic; they're not hooked into the "magical cache" HTTP/2 uses in any way.

Basically, I think you're assuming things here based on how Chrome implements things, but as you noted you're assuming stuff that is not defined anywhere and it's not clear to me that anyone other than Chrome implements it that way.

@bzbarsky
Copy link
Author

bzbarsky commented Aug 1, 2016

Oh, and I guess my point is that caching uncacheable stuff is a violation of HTTP/1.1 semantics. So if you have a <link rel="prefetch"> for a stylesheet and then load it on two different web pages there had better be at least two HTTP/1.1 loads, yes?

@igrigorik
Copy link
Member

@bzbarsky yeah, I was referring to h2 push. Re, preload: I'm referring to rel=preload.. are we talking about same thing? My understanding is that FF does not understand rel=preload yet.

Either way, to clarify a bit of confusion: my point here is that HTTP cache is not the only cache that browsers implement. Case in point, all of us have a separate "cache" for h2 pushed resources, and some other loads also end up in this special bucket. How and if they are then committed to HTTP cache is also a separate story -- e.g. h2 push is not committed to HTTP cache unless there is a matching response; preloads are committed immediately, and so on. We need to untangle this mess.

Oh, and I guess my point is that caching uncacheable stuff is a violation of HTTP/1.1 semantics. So if you have a for a stylesheet and then load it on two different web pages there had better be at least two HTTP/1.1 loads, yes?

Yes, I agree that would be a violation. However, prefetching a resource within the same context and then using it a little later is fine -- trivial user space example: I fetch a payload via XHR which is no-cache and then inject it at later time; preload is effectively the same.. a no-cache response is valid for lifetime of the context with ~one-time use semantics.

@bzbarsky
Copy link
Author

bzbarsky commented Aug 1, 2016

I'm referring to rel=preload.. are we talking about same thing?

Ah, sorry. I confused rel=preload and rel=next, sorry.

However, prefetching a resource within the same context and then using it a little later is fine

Yes, that seems reasonable. We definitely need to spec all this stuff. :(

@annevk
Copy link
Member

annevk commented Aug 4, 2016

I opened whatwg/fetch#354 to figure out the exact semantics of this cache. Input appreciated.

@igrigorik igrigorik added this to the Level 1 milestone Oct 13, 2016
@yoavweiss
Copy link
Contributor

OK, so it seems like Chrome and Firefox' behavior here differs wildly when it comes to non-cacheable prefetches, and we need to define what we want the behavior to be as part of #86, and then align implementations based on that.

@clelland
Copy link

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