Intent to Implement: <link rel=preload>

688 views
Skip to first unread message

Yoav Weiss

unread,
Mar 31, 2015, 9:03:45 AM3/31/15
to blink-dev
Primary eng email

Spec

Summary
Add support for <link rel="preload"> (and the equivalent HTTP Link header) to tell the browser that it should download a certain resource in a certain priority, since this resource will be needed later during current navigation.

Motivation
The preload relationship provides a declarative fetch primitive that enables developers to initiate a resource fetch and separate fetching from resource execution. As such, preload is a low-level primitive that enables applications to build custom resource loading and execution behaviors without hiding resources from the user agent and incurring delayed resource fetching penalties. For more, see introduction and use cases sections in the spec.
  
Compatibility Risk
Low.
It's a new feature with positive signals from IE and the WebKit team. Furthermore, the feature is a progressive enhancement, and no content would break for lack of browser support.
 
Firefox: No public signals
Internet Explorer: Positive signals
WebKit: Positive signals (F2F)
Web developers: Positive

Ongoing technical constraints
None

Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?
Yes

OWP launch tracking bug

Entry in Chromium Dashboard

Requesting approval to ship?
No

Chris Bentzel

unread,
Mar 31, 2015, 9:05:16 AM3/31/15
to Yoav Weiss, blink-dev, net...@chromium.org

Chris Bentzel

unread,
Mar 31, 2015, 9:17:05 AM3/31/15
to Yoav Weiss, blink-dev, net...@chromium.org
Is there a service that plans to experiment with this?

We already have a lot of complexity around pre-* in Chrome and I want to make sure that it offers measurable benefits over <link rel="prefetch">.

One other concern is what the shipping process is going to be like. I think it might be hard to understand the performance impact without deploying widely, but that's different from the normal blink process. But we also want the ability to yank it if it doesn't look to be much of a win.

Please make sure this is controlled by the "Prefetch resources to load pages more quickly" settings and related pref. bnc@ is a good point of contact for that.

On Tue, Mar 31, 2015 at 9:04 AM Chris Bentzel <cben...@chromium.org> wrote:
On Tue, Mar 31, 2015 at 9:03 AM Yoav Weiss <yo...@yoav.ws> wrote:

Ilya Grigorik

unread,
Mar 31, 2015, 12:31:07 PM3/31/15
to Chris Bentzel, Yoav Weiss, blink-dev, net...@chromium.org
On Tue, Mar 31, 2015 at 6:16 AM, Chris Bentzel <cben...@chromium.org> wrote:
We already have a lot of complexity around pre-* in Chrome and I want to make sure that it offers measurable benefits over <link rel="prefetch">.

Note that rel=preload offers very different semantics. rel=prefetch is speculative, best-effort, and is intended for fetching resources that may be required by next navigation context. By contrast, rel=preload is a declarative fetch: the UA must fetch the declared resource as soon as it encounters it and with indicated priority. In effect, rel=preload is a declarative fetch() that decouples fetching from processing and execution.. and allows developers to build own fetch+execution strategies. More on use cases here: http://w3c.github.io/preload/#use-cases

Is there a service that plans to experiment with this?

Yes, both Cloudflare and Fastly are on board...

"For CloudFlare having resource hints or a way of customer to indicate what assets will be required next will allow us pre-fetch and store at our edge. We already have a proprietary way of performing this and we plan to soon support rel='preload' at our edge. From our customers perspective any way of populating content into our edge nodes before they are requested by the browser is incredibly valuable. Cold cache load times are an important metric especially for sites that are significantly unique per user. There is also interest in improving web performance with services that can dynamically provide resource hints for customers pages.” - Andrew Galloni (CloudFlare)

“Preloading is one of the most impactful ways to speed up a website. The blocking behavior of scripts, stylesheets, and fonts and the complexity of how they're loaded and interact means that web developers can accelerate their site by explicitly telling the browser the key resources that are needed early. Link rel=preload accomplishes this by allowing developers to put this preload suggestions in the page's HEAD where they can be parsed early and kickoff downloads quickly. This benefit of suggesting key resources is also value to CDNs. When those key resources are requested from the CDN by the browser, it's possible that it'll be cache miss at the CDN level and require a (slow) trip back to the origin server. This turns a ~100ms delivery time to ~400ms or more. Since Link information can alternatively be sent as an HTTP response header, it's a lightweight way for CDNs to preload - thus having these necessary resources in the CDN's cache by the time the browser sends its request. This one feature thus has the ability to improve performance at both the browser AND the CDN.” - Steve Souders (ex-Fastly)
 
Please make sure this is controlled by the "Prefetch resources to load pages more quickly" settings and related pref. bnc@ is a good point of contact for that.

rel=preload shouldn't be subject to this pref because it's not a speculative or optional fetch, it's a MUST fetch: http://w3c.github.io/preload/#processing-model

ig
 
--
You received this message because you are subscribed to the Google Groups "net-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.
To post to this group, send email to net...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/net-dev/CAAuiYA-WnRGO1Ps%3DkCqeyTpOWC8UgyyQqNBnTcQ5b7pePFAYXA%40mail.gmail.com.

Chris Bentzel

unread,
Mar 31, 2015, 12:39:44 PM3/31/15
to Ilya Grigorik, Yoav Weiss, blink-dev, net...@chromium.org
Thanks for the explanations.

Ryan Sleevi

unread,
Mar 31, 2015, 1:11:40 PM3/31/15
to Chris Bentzel, Ilya Grigorik, Yoav Weiss, blink-dev, net...@chromium.org
What's unclear from the specification is how this relates to HTTP/2's Server Push, what the trade-offs are, and when one is more desirable than the other.

I highlight this, because it seems to introduce added complexity into both user agents and developers' toolkits, and understanding the appropriate and efficient use seems key to deriving any gains from it.

Is there a simple summary of "Why not Push?" As it stands, it seems all of the justifications in http://w3c.github.io/preload/#developer-server-and-proxy-initiated-fetching and http://w3c.github.io/preload/#early-fetch-of-critical-resources are seemingly addressible with push, and to be honest, I'm unconvinced that http://w3c.github.io/preload/#early-fetch-and-application-defined-execution is an inherently good or virtuous thing - for developers or for implementors.

Yoav Weiss

unread,
Apr 1, 2015, 4:58:45 AM4/1/15
to rsl...@chromium.org, Chris Bentzel, Ilya Grigorik, blink-dev, net...@chromium.org
On Tue, Mar 31, 2015 at 7:11 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
What's unclear from the specification is how this relates to HTTP/2's Server Push, what the trade-offs are, and when one is more desirable than the other.

I highlight this, because it seems to introduce added complexity into both user agents and developers' toolkits, and understanding the appropriate and efficient use seems key to deriving any gains from it.

Is there a simple summary of "Why not Push?" As it stands, it seems all of the justifications in http://w3c.github.io/preload/#developer-server-and-proxy-initiated-fetching and http://w3c.github.io/preload/#early-fetch-of-critical-resources are seemingly addressible with push

Push, while great, does not enable:
* Getting 3rd party hosted content as early as possible to the browser
* Early discovery of resources by the browser and their download according to the browser's priorities
* JS initiated fetches for resource that the client-side application logic knows will soon be needed.
 
, and to be honest, I'm unconvinced that http://w3c.github.io/preload/#early-fetch-and-application-defined-execution is an inherently good or virtuous thing - for developers or for implementors.
 
Would you care to elaborate why? JS based resource loaders have traditionally (and often unsuccessfully) hacked around the lack of this feature for years. There's a clear need for it, and it would be a great way to explain the current async/defer behaviors as well as enable various demonstrated loading use-cases, without trying to figure it all out in advance with markup.


Patrick Meenan

unread,
Apr 1, 2015, 9:46:02 AM4/1/15
to net...@chromium.org, rsl...@chromium.org, cben...@chromium.org, igri...@google.com, blin...@chromium.org, yo...@yoav.ws
The other common issue I have seen with push is that the server needs to predict the client's cache state to avoid pushing resources that are already in cache and doing that reliably doesn't work.  preload being client-initiated would still go through the local cache and only hit the wire for resources that aren't locally available.

Ilya Grigorik

unread,
Apr 1, 2015, 11:20:22 AM4/1/15
to Patrick Meenan, net...@chromium.org, rsl...@chromium.org, Chris Bentzel, blink-dev, Yoav Weiss
+1 to everything Pat & Yoav mentioned. I'll just add that server push+preload are complementary...

Server push is a transport feature that allows us to shave off an RTT on delivery of a resource, but it doesn't provide any particular mechanism for declaring which resources are to be pushed - i.e. there is no browser API, no JS callbacks notifying you of a received push, etc. Preload, on the other hand, is a declarative API for defining which resources need to be fetched, with what priority, with appropriate JS callbacks, etc. 

As such, the developer can use preload to indicate which resources should be fetched, and a smart server can look for these declarations (in HTML markup or Link headers) and optionally use server push to shave off another RTT on delivery, or it can just let the UA initiate the request (pro: UA would only do so if it's a local cache miss). Also server push is limited to same-origin resources, whereas the the site may also want to preload resources from a third-party (e.g. a library, popular widget, etc), and preload enables that. 

In short, push is a latency optimization and preload is the declarative mechanism by which we can infer which resources may be eligible for server push.

On Tue, Mar 31, 2015 at 10:11 AM, Ryan Sleevi <rsl...@chromium.org> wrote:
I'm unconvinced that http://w3c.github.io/preload/#early-fetch-and-application-defined-execution is an inherently good or virtuous thing - for developers or for implementors.

It's a sorely needed and missing primitive. The simplest example is the long outstanding developer request for "async CSS", which is easily implementable with preload in a performant manner (visible to preloader, fetched with correct priority, etc), and also allows developers to define custom behaviors that go well beyond 'async' - e.g. defer execution until some additional+app-specific conditions are met. Same applies for any other content type and, best of all, preload can be used to implement various load/execute strategies that span any mix of content-types.. It's a building block for custom+smart resource loading strategies.

ig

guy...@gmail.com

unread,
Apr 1, 2015, 6:38:21 PM4/1/15
to blin...@chromium.org
Great to see this getting actually implemented.

At Akamai we're definitely advocates for this, and have been calling for standardizing such functionality for a while.

We've been doing such preloading for a long time, but had to work around the lack of standards to achieve it. We've been prefetching resources to the edge server to warm caches ahead of time for many years, and it provides real and substantial gains. We're also using preload alternatives to fetch resources to the browser ahead of time (using a variety of tricks, as we had no standard), which shows great acceleration on some sites.

So in summary - this can bring true value, looking forward to seeing it grow in Blink and beyond!

Cheers,
Guypo

Ryan Sleevi

unread,
Apr 2, 2015, 10:45:55 PM4/2/15
to Ilya Grigorik, Patrick Meenan, net...@chromium.org, Ryan Sleevi, Chris Bentzel, blink-dev, Yoav Weiss
On Wed, Apr 1, 2015 at 8:19 AM, Ilya Grigorik <igri...@google.com> wrote:
+1 to everything Pat & Yoav mentioned. I'll just add that server push+preload are complementary...

Sounds like these are all great answers to be put in a spec or related note ;)
 
Server push is a transport feature that allows us to shave off an RTT on delivery of a resource, but it doesn't provide any particular mechanism for declaring which resources are to be pushed - i.e. there is no browser API, no JS callbacks notifying you of a received push, etc. Preload, on the other hand, is a declarative API for defining which resources need to be fetched, with what priority, with appropriate JS callbacks, etc. 

Conversely, server push allows limited control over the stream but otherwise lets the browser work through different strategies to load resources.

I guess my point was more that I see it as a double-edged sword - the more fundamental types we expose to the platform, the less ability we have to actually change the platform. For example, consider the hypothetical API that exposes some set of details about the TLS connection. Done poorly, this could entirely prevent the ability to experiment with new protocols (e.g. QUIC) or rethink current protocols (e.g. TLS 1.3).

I look at CSS transforms and see both the care that developers must take and the complexity that implementors must take to keep things performant, and I have a deep concern for network loading becoming like that. Service Workers are a prime example - powerfully exciting, in some ways, but conceptually broken in others, and which will no doubt continue to cause pain and heartache (authentication flows are a prime example of this unintended, and unsolved, complexity).
 
In short, push is a latency optimization and preload is the declarative mechanism by which we can infer which resources may be eligible for server push.

Well, it's more than just declarative. I suppose because I was looking at the matching rules (which themselves are vague, but I suppose implementation experience is how we make what's vague concrete - or at least, what's buggy, ossified and required). I see Will already commented pretty heavily back in 2014, and yeah, that captured some of my concerns.
 

On Tue, Mar 31, 2015 at 10:11 AM, Ryan Sleevi <rsl...@chromium.org> wrote:
I'm unconvinced that http://w3c.github.io/preload/#early-fetch-and-application-defined-execution is an inherently good or virtuous thing - for developers or for implementors.

It's a sorely needed and missing primitive. The simplest example is the long outstanding developer request for "async CSS", which is easily implementable with preload in a performant manner (visible to preloader, fetched with correct priority, etc), and also allows developers to define custom behaviors that go well beyond 'async' - e.g. defer execution until some additional+app-specific conditions are met. Same applies for any other content type and, best of all, preload can be used to implement various load/execute strategies that span any mix of content-types.. It's a building block for custom+smart resource loading strategies.

So I suppose I should have elaborated more. I totally understand the _why_ being argued for those. I'm just not convinced of its inherent goodness. Don't get me wrong, I'm totally familiar with https://extensiblewebmanifesto.org/ and how often it's quoted for "platforms of primitives, not primitive platforms" and such, but I'm understandably apprehensive that attempting to explain the platform in this way may be furthering either a footgun or a 'sync XHR' cargo-cult in which the ability to optimize disappears.

I get that more information can lead to smarter execution, but at the same time, more requirements represent a greater API contract. The absence of a strict API contract has lead to all sorts of nifty experiments in the net stack, and some genuinely useful results (hi there HTTP/2!), but at the same time, I'm aware it's been limiting.

I don't think my concerns should block implementation; that is, I think the spec could be better explained in some areas (and this thread shows there's good information to be had that isn't in it), it clearly needs some work in other areas that we're unlikely to get until more implementation experience (matching requests and the MUST keep available requirements), and overall can be quite helpful.

One last thought experiment before you go off - given that you've put a lot of thought into how this can be helpful, can you put some thought into what the anti-patterns might be or look like? I think the work on idiomatic promises is a great example of how working through how the syntax enables boneheaded things, and what you "should" do instead, can lead to better experience for all. I apologize that I haven't participated in the spec discussions (and am unlikely to), and this may have already been covered, but... what's the worst code you could think of that'd be enabled by this, and what can developers do to avoid that?

Ilya Grigorik

unread,
Apr 3, 2015, 3:00:35 PM4/3/15
to rsl...@chromium.org, Patrick Meenan, net...@chromium.org, Chris Bentzel, blink-dev, Yoav Weiss
On Thu, Apr 2, 2015 at 7:45 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
I don't think my concerns should block implementation; that is, I think the spec could be better explained in some areas (and this thread shows there's good information to be had that isn't in it), it clearly needs some work in other areas that we're unlikely to get until more implementation experience (matching requests and the MUST keep available requirements), and overall can be quite helpful.

Yep, and these are all great questions and feedback -- appreciate it! 
 
One last thought experiment before you go off - given that you've put a lot of thought into how this can be helpful, can you put some thought into what the anti-patterns might be or look like? I think the work on idiomatic promises is a great example of how working through how the syntax enables boneheaded things, and what you "should" do instead, can lead to better experience for all. 

Come to think of it, I'd love to see this in every spec... "How (and where) not to use this API" :-)

I'll take a run at adding some "implementation" text around interop with server push, anti-patterns, etc. 

ig
 

Dimitri Glazkov

unread,
Apr 6, 2015, 12:15:06 PM4/6/15
to Yoav Weiss, net...@chromium.org, blink-dev, Ilya Grigorik
A couple of questions:

1) What's the relationship between Service Worker and this new feature?

2) How does it fit into the rational web platform/extensible web narrative? In other words, what are the primitives that I would need in order build my own <link rel=preload> custom element?

:DG<

Yoav Weiss

unread,
Apr 6, 2015, 5:52:15 PM4/6/15
to Dimitri Glazkov, net...@chromium.org, blink-dev, Ilya Grigorik
On Mon, Apr 6, 2015 at 6:15 PM, Dimitri Glazkov <dgla...@chromium.org> wrote:
A couple of questions:

1) What's the relationship between Service Worker and this new feature?

An installed Service Worker can intercept preload initiated requests, just like any others.


2) How does it fit into the rational web platform/extensible web narrative? In other words, what are the primitives that I would need in order build my own <link rel=preload> custom element?

In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.
 

:DG<

Ryan Sleevi

unread,
Apr 6, 2015, 5:58:34 PM4/6/15
to Yoav Weiss, Dimitri Glazkov, net...@chromium.org, blink-dev, Ilya Grigorik
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

Ilya Grigorik

unread,
Apr 6, 2015, 8:05:41 PM4/6/15
to rsl...@chromium.org, Yoav Weiss, Dimitri Glazkov, net...@chromium.org, blink-dev
SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document, which is what preload is all about.

In terms of primitives that explain rel=preload:
- rel=preload is Fetch in declarative form, so fetch() is the underlying primitive that we're building on / explains rel=preload.
- the benefit with declarative form is that we don't need JS execution, which unblocks preloader + allows clean interop with various optimization services

ig

Ben Maurer

unread,
Apr 6, 2015, 8:16:54 PM4/6/15
to net...@chromium.org, yo...@yoav.ws, blin...@chromium.org
Will there be a way for a website to test for the implementation of this feature? For example, imagine a site wanted to use <link rel=preload> to load a stylesheet, without blocking on it. On older browsers, it would have to fall back to some other strategy (eg, xhr or a blocking rel=stylesheet). How would sites know to do that?

Ilya Grigorik

unread,
Apr 6, 2015, 8:34:08 PM4/6/15
to Ben Maurer, net...@chromium.org, Yoav Weiss, blink-dev

On Mon, Apr 6, 2015 at 5:16 PM, Ben Maurer <ben.m...@gmail.com> wrote:
Will there be a way for a website to test for the implementation of this feature? For example, imagine a site wanted to use <link rel=preload> to load a stylesheet, without blocking on it. On older browsers, it would have to fall back to some other strategy (eg, xhr or a blocking rel=stylesheet). How would sites know to do that?

Dominic Cooney

unread,
Apr 7, 2015, 1:00:11 AM4/7/15
to Ilya Grigorik, rsl...@chromium.org, Yoav Weiss, Dimitri Glazkov, net...@chromium.org, blink-dev
On Tue, Apr 7, 2015 at 9:04 AM, 'Ilya Grigorik' via blink-dev <blin...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:58 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document,

Actually, a Service Worker can exercise some control of those things. For example, in response to any event it can start new fetches (simply by calling "fetch".)

With Streams, I could implement a Service Worker that scans the content of a document is it's being loaded and calls fetch when it encounters <link rel="preload">. With Request context it could even communicate to the resource scheduler that this is a prefetch, although I'm not sure that is hooked up yet.

Some limitations are:

- If there's no Service Worker installed, the Service Worker can't do anything. So this wouldn't work for first load.
- Chrome/Blink has already integrated a bunch of stuff that can interpret a byte stream as HTML content and scan for stuff in it. Of course this is possible to replicate this in JavaScript, but it's an investment. Whether you think this is a big problem depends on how much you trust web developers and how patient you are that this Extensible Web stuff will pay off.

Yoav Weiss

unread,
Apr 7, 2015, 5:14:02 AM4/7/15
to Dominic Cooney, Ilya Grigorik, rsl...@chromium.org, Dimitri Glazkov, net...@chromium.org, blink-dev
On Tue, Apr 7, 2015 at 7:00 AM, Dominic Cooney <domi...@chromium.org> wrote:

On Tue, Apr 7, 2015 at 9:04 AM, 'Ilya Grigorik' via blink-dev <blin...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:58 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document,

Actually, a Service Worker can exercise some control of those things. For example, in response to any event it can start new fetches (simply by calling "fetch".)

With Streams, I could implement a Service Worker that scans the content of a document is it's being loaded and calls fetch when it encounters <link rel="preload">. With Request context it could even communicate to the resource scheduler that this is a prefetch, although I'm not sure that is hooked up yet.


Yeah, in theory it could be implemented in SW, if we'd ask developers to re-implement HTML tokenization and parsing in JS. The same is true for other core features (e.g. PreloadScanner).
I think we can all agree that this is mostly a thought experiment. (i.e. I don't think anyone here seriously expects Web developers to actually do this in production) 

Some limitations are:

- If there's no Service Worker installed, the Service Worker can't do anything. So this wouldn't work for first load.
- Chrome/Blink has already integrated a bunch of stuff that can interpret a byte stream as HTML content and scan for stuff in it. Of course this is possible to replicate this in JavaScript, but it's an investment.

Another limitation: probable performance impact since tokenization & parsing would happen twice. 

 

Dominic Cooney

unread,
Apr 8, 2015, 12:02:47 AM4/8/15
to Yoav Weiss, Ilya Grigorik, rsl...@chromium.org, Dimitri Glazkov, net...@chromium.org, blink-dev
On Tue, Apr 7, 2015 at 6:13 PM, Yoav Weiss <yo...@yoav.ws> wrote:

On Tue, Apr 7, 2015 at 7:00 AM, Dominic Cooney <domi...@chromium.org> wrote:

On Tue, Apr 7, 2015 at 9:04 AM, 'Ilya Grigorik' via blink-dev <blin...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:58 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document,

Actually, a Service Worker can exercise some control of those things. For example, in response to any event it can start new fetches (simply by calling "fetch".)

With Streams, I could implement a Service Worker that scans the content of a document is it's being loaded and calls fetch when it encounters <link rel="preload">. With Request context it could even communicate to the resource scheduler that this is a prefetch, although I'm not sure that is hooked up yet.


Yeah, in theory it could be implemented in SW, if we'd ask developers to re-implement HTML tokenization and parsing in JS. The same is true for other core features (e.g. PreloadScanner).
I think we can all agree that this is mostly a thought experiment. (i.e. I don't think anyone here seriously expects Web developers to actually do this in production) 

Let me preface this by saying: I'm not very familiar with <link rel="preload"> and I don't have an opinion either way about it. That said...

This argument seems to put an upper bound on the value of <link rel="preload">, because some web developers seem pretty motivated to do things to improve performance. With things like Polymer and Service Worker, framework authors can make things pretty accessible to "ordinary" web developers. So in effect it seems like you're saying that the performance benefit of preload is roughly the cost of scanning bytes in JavaScript in a background thread, or that difference in performance would be decisive? I haven't measured it but I expect V8 can scan bytes pretty fast...
 
Some limitations are:

- If there's no Service Worker installed, the Service Worker can't do anything. So this wouldn't work for first load.
- Chrome/Blink has already integrated a bunch of stuff that can interpret a byte stream as HTML content and scan for stuff in it. Of course this is possible to replicate this in JavaScript, but it's an investment.

Another limitation: probable performance impact since tokenization & parsing would happen twice. 

Yes, if one party makes an ideal component and integrates it very well, performance is better. But on the other hand, we can't do everything, and sometimes "ideal" depends on context outside of our control (that is, we can integrate well with stuff within Chrome, but the web author can integrate stuff with their website.) To take an extreme example, we could integrate one version of jQuery into Chrome and optimize it, etc. but we wouldn't want to do that because as we've seen jQuery continued to make changes and improvements over some time that we could not have predicted.

Dominic

Noel Gordon

unread,
Apr 8, 2015, 3:04:12 AM4/8/15
to Dominic Cooney, Yoav Weiss, Ilya Grigorik, rsl...@chromium.org, Dimitri Glazkov, net...@chromium.org, blink-dev

On 8 April 2015 at 14:02, Dominic Cooney <domi...@chromium.org> wrote:
... cost of scanning bytes in JavaScript in a background thread, or that difference in performance would be decisive? I haven't measured it but I expect V8 can scan bytes pretty fast...

(Not a reply to Dominic's questions) but the "how fast does V8 scan bytes..." part made me wonder. Seems V8 has advanced in that area recently ...


~noel







Yoav Weiss

unread,
Apr 8, 2015, 4:09:49 AM4/8/15
to Dominic Cooney, Ilya Grigorik, Ryan Sleevi, Dimitri Glazkov, net...@chromium.org, blink-dev
On Wed, Apr 8, 2015 at 6:02 AM, Dominic Cooney <domi...@chromium.org> wrote:
On Tue, Apr 7, 2015 at 6:13 PM, Yoav Weiss <yo...@yoav.ws> wrote:

On Tue, Apr 7, 2015 at 7:00 AM, Dominic Cooney <domi...@chromium.org> wrote:

On Tue, Apr 7, 2015 at 9:04 AM, 'Ilya Grigorik' via blink-dev <blin...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:58 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document,

Actually, a Service Worker can exercise some control of those things. For example, in response to any event it can start new fetches (simply by calling "fetch".)

With Streams, I could implement a Service Worker that scans the content of a document is it's being loaded and calls fetch when it encounters <link rel="preload">. With Request context it could even communicate to the resource scheduler that this is a prefetch, although I'm not sure that is hooked up yet.


Yeah, in theory it could be implemented in SW, if we'd ask developers to re-implement HTML tokenization and parsing in JS. The same is true for other core features (e.g. PreloadScanner).
I think we can all agree that this is mostly a thought experiment. (i.e. I don't think anyone here seriously expects Web developers to actually do this in production) 

Let me preface this by saying: I'm not very familiar with <link rel="preload"> and I don't have an opinion either way about it. That said...

This argument seems to put an upper bound on the value of <link rel="preload">, because some web developers seem pretty motivated to do things to improve performance. With things like Polymer and Service Worker, framework authors can make things pretty accessible to "ordinary" web developers. So in effect it seems like you're saying that the performance benefit of preload is roughly the cost of scanning bytes in JavaScript in a background thread, or that difference in performance would be decisive? I haven't measured it but I expect V8 can scan bytes pretty fast...

Not even close to what I was saying.

Dominic Cooney

unread,
Apr 8, 2015, 4:36:42 AM4/8/15
to Yoav Weiss, Ilya Grigorik, Ryan Sleevi, Dimitri Glazkov, net...@chromium.org, blink-dev
On Wed, Apr 8, 2015 at 5:09 PM, Yoav Weiss <yo...@yoav.ws> wrote:


On Wed, Apr 8, 2015 at 6:02 AM, Dominic Cooney <domi...@chromium.org> wrote:
On Tue, Apr 7, 2015 at 6:13 PM, Yoav Weiss <yo...@yoav.ws> wrote:

On Tue, Apr 7, 2015 at 7:00 AM, Dominic Cooney <domi...@chromium.org> wrote:

On Tue, Apr 7, 2015 at 9:04 AM, 'Ilya Grigorik' via blink-dev <blin...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:58 PM, Ryan Sleevi <rsl...@chromium.org> wrote:
On Mon, Apr 6, 2015 at 2:52 PM, Yoav Weiss <yo...@yoav.ws> wrote:
In its essence, preload is a declarative fetch. 
One capability preload has which is missing from current fetch is the ability to declare the resource's download priority. (the `as` attribute)
I believe that's the only missing primitive to implement a custom <link rel=preload>.

So if https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 was resolved, this could be implemented via Service Workers (effectively)?

SW does not provide the same functionality. As Yoav mentioned, preload is declarative fetch(): it enables developers to declare which resources need to be fetched and with which settings; these declarations do not require JS execution (and can be delivered via markup or HTTP headers), which makes them preload-scanner and optimization-server/proxy friendly; they allow application to decouple download from processing; they enable UA to initiate early(er) fetch of critical resources that may be hidden or delayed otherwise... SW can, of course, observe and respond to these requests, but it cannot and does not control when+which resource fetches are initiated by parent document,

Actually, a Service Worker can exercise some control of those things. For example, in response to any event it can start new fetches (simply by calling "fetch".)

With Streams, I could implement a Service Worker that scans the content of a document is it's being loaded and calls fetch when it encounters <link rel="preload">. With Request context it could even communicate to the resource scheduler that this is a prefetch, although I'm not sure that is hooked up yet.


Yeah, in theory it could be implemented in SW, if we'd ask developers to re-implement HTML tokenization and parsing in JS. The same is true for other core features (e.g. PreloadScanner).
I think we can all agree that this is mostly a thought experiment. (i.e. I don't think anyone here seriously expects Web developers to actually do this in production) 

Let me preface this by saying: I'm not very familiar with <link rel="preload"> and I don't have an opinion either way about it. That said...

This argument seems to put an upper bound on the value of <link rel="preload">, because some web developers seem pretty motivated to do things to improve performance. With things like Polymer and Service Worker, framework authors can make things pretty accessible to "ordinary" web developers. So in effect it seems like you're saying that the performance benefit of preload is roughly the cost of scanning bytes in JavaScript in a background thread, or that difference in performance would be decisive? I haven't measured it but I expect V8 can scan bytes pretty fast...

Not even close to what I was saying.

OK, I might have missed the point. This is probably a subjective thing, but to me phrases like "I think we can all agree X" and "nobody here seriously expects Y" is a bit of an unfair rhetorical twist; I do think that, if not now then soon, Service Workers should be usable for implementing this sort of thing, which is what I was trying to explain above. We've seen people experiment with things a bit like this, although not exactly this.

I guess I can summarize my position in two points:

1. Some of what was shared above about what Service Workers can or can't do could have been more accurate. They can express a subset of preload. The main limitation is that for first load of an origin, the preloads would not be particularly "pre" because you'd have to load the Service Worker script first.

2. Historically browsers have exposed more, higher-level, less orthogonal things; but that's a choice we make. Each one of those axes has its pros and cons.

Ilya Grigorik

unread,
Apr 8, 2015, 9:06:36 PM4/8/15
to Dominic Cooney, Yoav Weiss, Ryan Sleevi, Dimitri Glazkov, net...@chromium.org, blink-dev
On Wed, Apr 8, 2015 at 1:36 AM, Dominic Cooney <domi...@chromium.org> wrote:
1. Some of what was shared above about what Service Workers can or can't do could have been more accurate. They can express a subset of preload.

Yep, that's fair. What you're pointing out here is that we can use SW to "explain" the preload scanner: observe the response stream (if and when allowed); scan for resource declarations you care about; fire off fetches as necessary... which is awesome, and I'd love to see someone experiment with it! That said, regardless of how the preload scanner is implemented, rel=preload is its own, separate, and a much needed optimization layer...

Preload allows the application to _explicitly_ declare what it will need ahead of time: the actual resource declaration may come (too) late in the stream, or not at all (dynamically injected resource, etc). For the former case, having an explicit signal from the application in a form of rel=preload (or Link header) allows the native, or SW-driven, preload scanner (and other optimization services) to initiate these requests much sooner. For the latter case, it enables the application to initiate fetch for resources that are otherwise invisible until much later in the document lifecycle. Then, once preload fetch is complete, preload allows the document to supply own processing logic - e.g. execute now ("async" semantics for any content type), delay and wait for others, and so on... plus other use cases: http://w3c.github.io/preload/#use-cases

tl;dr: SW can leverage preload to its advantage. Another explainer section I should probably add to the spec, in addition to interaction with h2 push.. :)

ig
Reply all
Reply to author
Forward
0 new messages