Serviceworker: Consider mechanisms to bypass the service worker for things that we know won't be in it's cache

Created on 13 Dec 2016  路  15Comments  路  Source: w3c/ServiceWorker

The Problem

There will always be some number of resources that we cannot cache in the Service Worker. Perhaps this is segments of a 360 VR video or something like a profile picture that just changed. In many case it's possible that the client will know in advance that the Service Worker does not have this resource cached yet the request for it still need to go through the Service Worker.

Right now the process of sending a request from the main thread to a Service Worker can take a few milliseconds in many implementations. Then we have to wait on the event loop in the Service Worker (which we always have to do even in the best case scenario). Facebook tends to send large bursts of resource requests as the page loads. If we send 40 or so requests from the window at once, while the first few may be quick, the other events get tacked onto the end of the Service Worker event loop and end up getting delayed quite a bit before they can hit the network. Even though the Service Worker won't call respondWith for these events they still get delayed by the busy Service Worker event queue.

Proposed Solution

The window will generally know it has a resources that there's no way the Service Worker has in cache. It'd be nice if there was a way for the service worker to be totally bypassed when this resource is requested. Perhaps this is an API on the service worker registration that lets you mark URLs as bypassable, perhaps we add this as a fetch option and let you add fetch options to html tags, perhaps we come up with some url scheme that let's you bypass the sw. I'm not sure what the right solution is, but I'd like to start thinking about what one could be :)

apr-2017-f2f

Most helpful comment

Sounds like another use case solved by Jake's static routing proposal:

https://github.com/w3c/ServiceWorker/issues/920#issuecomment-229016073

I do wonder how much headroom there is for this kind of optimization, though. At some point we are going to bottleneck on the main thread or limits on parallel network requests. That limits how much of a win we can get with something like this.

All 15 comments

Sounds like another use case solved by Jake's static routing proposal:

https://github.com/w3c/ServiceWorker/issues/920#issuecomment-229016073

I do wonder how much headroom there is for this kind of optimization, though. At some point we are going to bottleneck on the main thread or limits on parallel network requests. That limits how much of a win we can get with something like this.

Static routes would be the declarative solution, but I think at some point we want something on fetch() too. E.g., you might want to bypass foreign fetch and such.

Yeah, for the non-declarative solution we could expose the "use-service-workers" value that's in-progress.

My impression was that @n8schloss wanted to use this for network requests triggered by page elements, etc. So not sure adding a field to RequestInit is enough. (Although I think thats a good idea.)

Yeah, but just like referrerpolicy is on both, I could imagine service-workers mode to be on both in a similar manner.

But yeah, I think @n8schloss is looking for something declarative.

$TATIC ROUTEZ

Regarding the RequestInit or tag attribute, would that bypass foreign fetch SWs as well or only same-origin SWs? It seems a site could reason about their own SW implementation, but maybe not about what other origins are doing.

Depends on what granularity we offer. For specifications we need "none", "all", and "foreign" (only foreign service workers) thus far.

@jakearchibald declarative can also be <img serviceworker=foreign src=...>.

@n8schloss you wrote:

If we send 40 or so requests from the window at once, while the first few may be quick, the other events get tacked onto the end of the Service Worker event loop and end up getting delayed quite a bit before they can hit the network.

Did you measure this? This sounds extremely unlikely to be so slow as you suggest. Forty event loop turns should be super quick.

Did you measure this? This sounds extremely unlikely to be so slow as you suggest. Forty event loop turns should be super quick.

I expect a lot of this has to do with current implementation details. I believe networking has to go through the main thread in both firefox and chrome today. So after firing the SW FetchEvent you likely have to return to the main thread to start the actual network. This could be blocked on http parse, script, or anything else running there.

I'm sure this will improve over time, but one way to do that is to let the page give us precise information about intent so we can get the request to the right place with a minimum of main thread touches.

Did you measure this? This sounds extremely unlikely to be so slow as you suggest. Forty event loop turns should be super quick.

We did a number of measurements on this and there is currently significant overhead, plus even in a perfect world this can get blocked a lot on script. If I know that the SW isn't going to respond to a particular fetch event then having it get blocked at all on a SW is a waste.

Yeah, for the non-declarative solution we could expose the "use-service-workers" value that's in-progress.

That sounds amazing imo! Thinking about this more there will be times where we know far enough in advance that we should skip the SW so declarative routing will work. But other times it would make more sense to do it within fetch options. Both have real value and the more I think about it the more I feel like doing both is the right call.

F2F: I'd like to get an impression of how much of the slow here is "Chrome problems", I believe we get stuck on the main thread a bit with lots of requests.

As I mentioned here, there is a lot of time spent in Chrome in routing to the service worker when there are a lot of requests - though I am not able to replicate this reliably.

Hi,
In case of too many requests I have seen that "Request To Service Worker" time is too high compared to when we don't have service worker.

The delta is usually 500ms with and without.

Thanks

F2F: Adding service worker mode to fetch sounds easy. Exposing fetch options to various HTML elements is harder. We end up with lots of JSON in attributes. Good ideas needed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lewispham picture lewispham  路  12Comments

publicocean0 picture publicocean0  路  4Comments

jakearchibald picture jakearchibald  路  10Comments

lewispham picture lewispham  路  4Comments

liebrand picture liebrand  路  6Comments