Skip to content
This repository has been archived by the owner on May 5, 2022. It is now read-only.

Explain rel=preload in terms of Fetch #81

Closed
annevk opened this issue Dec 7, 2016 · 13 comments
Closed

Explain rel=preload in terms of Fetch #81

annevk opened this issue Dec 7, 2016 · 13 comments

Comments

@annevk
Copy link
Member

annevk commented Dec 7, 2016

@wycats mentioned that currently rel=preload is a mandatory high-priority fetch, but since it's not explained in terms of Fetch you can't emulate it in workers and it's actually hard tell what it means in detail. Seems like something we should fix as we presumably still care about the "Extensible Web".

@wycats
Copy link

wycats commented Dec 7, 2016

A little more context.

From the fetch spec:

A request has an associated priority

From the <link rel='preload'> spec:

Both prefetch ([RESOURCE-HINTS]) and preload declare a resource and its fetch properties, but differ in how and when the resource is fetched by the user agent: prefetch is an optional and low-priority fetch for a resource that might be used by a subsequent navigation; preload is a mandatory and high-priority fetch for a resource that is necessary for the current navigation.

Both specs refer to "priority", but there is no connection in the spec between these two concepts.

@igrigorik
Copy link
Member

@wycats mentioned that currently rel=preload is a mandatory high-priority fetch, but since it's not explained in terms of Fetch you can't emulate it in workers and it's actually hard tell what it means in detail.

There is a lot to be done to explain prioritization in the platform... We added a "vague note about priority to at least acknowledge it exists" and we haven't made much progress since. On a practical level, all UA's do apply some heuristics for relative prioritization of how resources are loaded: this varies based on lifecycle of the page, the protocol, and other conditions (e.g. type of network, etc).

Which is to say, yes, it is hard to tell what it means in detail, and it's a medium~large undertaking that I'd love to see someone take on. Also, this is not specific to preload in any way, it applies to every fetch, and I think it's a discussion better had in the context of Fetch spec - e.g. how does destination type affect prioritization, what is prioritization, etc. Preload, specifically, sets the destination via as, and defers the rest to Fetch.

From the spec...

We can probably wordsmith that note to be a bit more clear about the intent, which is simply to point out the difference between prefetch and preload.. By "high priority" it's simply meant to highlight that the UA should not defer loading the resource, as it may do for prefetch.

... prefetch is an optional fetch that could be deferred by the user agent to reduce contention with other critical resources for the current page, whereas preload is a fetch that is required by the current page and needs to be processed immediately.

Does that sound a bit better? My proposal here is that we (a) update the note and remove 'priority' to minimize confusion, and (b) start a new thread on Fetch repo to "explain prioritization".

@annevk
Copy link
Member Author

annevk commented Dec 8, 2016

Well, the request here is to explain preload/prefetch. Even if Fetch explains prioritization, we'd still need updates here to make use of it.

@igrigorik
Copy link
Member

Prefetch is covered in Resource Hints. This spec is for Preload, so let's focus on that..

  • We define preload keyword
  • Processing section defines "appropriate times" to obtain the resource, same as other <link> types in the HTML spec.
    • Obtain step defines how to processes and set destination (via as) for the underlying Fetch.

What else is missing? There is really nothing else to say, I think, for the prioritization bits in Preload.

@annevk
Copy link
Member Author

annevk commented Dec 8, 2016

So <link rel=preload href=x> is effectively equivalent to <script>fetch('x')</script>?

@igrigorik
Copy link
Member

As defined, yes. If you add "as=image" on preload, then it would be ~equivalent to <img src="...">.

@igrigorik
Copy link
Member

@wycats @annevk anything actionable here?

@annevk
Copy link
Member Author

annevk commented Dec 16, 2016

What do you mean with "as defined"? It sounds like you're saying they are different.

@igrigorik
Copy link
Member

No, no.. "Equivalent" :)

@Krinkle
Copy link
Member

Krinkle commented May 6, 2017

So <link rel=preload href=x> is effectively equivalent to <script>fetch('x')</script>?
As defined, yes.

(I don't know if this issue is meant only to deal with request behaviour, or also with processing behaviour after receiving a response. Since @annevk mentioned possible emulation in Service Workers, I'm assuming the responsive processing is in scope of this issue as well. If not, I could create a separate issue for that.)

While the way the request is made is equivalent to a plain fetch(), the way the response is processed is different because Preload responses must not just simply get put in the HTTP cache and otherwise discarded. It must be kept available for re-use by exactly 1 subsequent "real" request, regardless of revalidation or no-cache requirements.

Given an attempt to emulate preload by looking for the Link-preload headers in a Service Worker and making a fetch() for the specified resource, is not sufficient. Although I suppose one could consider it the worker's responsibility to cache the result in a way that will match any future incoming fetch event regardless of caching headers, and do so "once", after which it would be moved to the regular cache.

@yoavweiss
Copy link
Contributor

While the way the request is made is equivalent to a plain fetch(), the way the response is processed is different because Preload responses must not just simply get put in the HTTP cache and otherwise discarded. It must be kept available for re-use by exactly 1 subsequent "real" request, regardless of revalidation or no-cache requirements.

Yeah, we need to define a "preload cache".

Given an attempt to emulate preload by looking for the Link-preload headers in a Service Worker and making a fetch() for the specified resource, is not sufficient. Although I suppose one could consider it the worker's responsibility to cache the result in a way that will match any future incoming fetch event regardless of caching headers, and do so "once", after which it would be moved to the regular cache.

You could in fact implement a "preload cache" as part of your SW code.

Some parts are missing in Fetch, I think, in order for you to do that. e.g. I don't think you can set the appropriate destination for fetch() initiated requests. I don't think that part should be covered by this issue though.

@yoavweiss
Copy link
Contributor

@annevk - could you detail what is missing in your opinion for such "explaining in terms of Fetch"?

One big item on my list is defining the preload cache, but it seems like something that should be defined inside Fetch. Do you agree? If so, I'll open an issue there specific to the preload cache. (I think the preload cache should be decoupled from whatwg/fetch#354 as it should operate at a totally separate layer)

Anything else?

@yoavweiss
Copy link
Contributor

@annevk - I opened #97 to separately track the preload cache work. I'm closing this one and I'm sure there's more work other than that, but please reopen if you think there are other issues related to the integration of this spec and Fetch.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants