Re: [slightlyoff/ServiceWorker] Eliminating SW startup latency for common case (#920)

Without concrete data on the problem, it's difficult to assess solutions. Service worker startup is not free - but we need to assess when that cost significantly detracts from the benefits. It could be:

**I have no fetch event. I'm paying the startup cost for no reason.**

We solved this in #718, but [Chrome hasn't landed it yet](https://bugs.chromium.org/p/chromium/issues/detail?id=605844). This is the case for at least one of the large sites reporting this regression.

**I have a fetch event but it doesn't `respondWith`. The result is blocked on SW startup, despite the SW having no impact on the result.**

We have an existing solution that we can apply here: [passive listeners](https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md). Although we may need to disable reading the request body in this case.

**I have a fetch event, it sometimes calls `respondWith`. If it does, it sometimes fetches `event.request`.**

I *think* this is the case the proposed solution is aiming for, but I really want to hear more about sites that use this pattern.

```js
self.onactivate = (e) => {
  // If unset, preflight requests are sent without special marking
  e.setPreflightHeader("X-Site-Specific-Header", "thinger");

  // ...
}
```

This suggests the preflight will happen for each and every request (or just navigation requests for some reason?), which feels like a huge change. If I serve a 3gb video from the cache, what happens to the preflight? Is the user going to end up downloading the 3gb again, or will the stream be aborted? Either way, as a developer, I feel like I've just lost a lot of control.

```js
self.onfetch = (e) => {
  if (e.preflightResponse) {
    // This is a navigation fetch which has already been issued.
    // If the `preflightResponse` isn't used, then everything proceeds as
    // if it hadn't been sent in the first place.
  }
}
```

If the fetch event is blocked on a preflight response, you've killed service worker as a means for creating offline-first experiences. One way around this is to make `e.preflightResponse` undefined if the fetch event can fire before we have the preflight response. This becomes unpredictable and another loss of control. But furthermore:

```js
self.onfetch = event => {
  event.respondWith(
    event.preflightResponse || fetch(event.request)
  )
}
```

If `preflightResponse` is fired because the fetch event won the race, we execute `fetch(event.request)`, making the request a second time. You could work around this by making `preflightResponse` a promise, but things are getting messy. You're still going to get the double request for existing service workers.

Additionally, using the response is still blocked on the SW, as the fetch event is always consulted. Is that ok? Again I want more concrete data.

The preflight is always going to happen, but I have to opt into using it. It seems really weird that the preflight isn't an opt-in, there isn't an opt-out, yet *using* the preflight is opt-in.

> The goal however isn't to be super declarative about deciding what "routes" are handled in which style. Instead, it's to allow the maximum of flexibility for cooperating servers and clients to eliminate SW startup latency.

I see you put that bit in because I'm in favour of a route-based solution. 😄  But I don't see how routes are a worse solution, and your proposal doesn't feel awfully flexible, easy to reason about, or even address (what seems to be) the route of the problem.

A route-based solution should allow a developer to declare "for requests that look like this, do this", in a way that can at the very least started while the service worker boots up. This wins over the proposed preflight solution because:

* It needn't be restricted to navigation requests
* It's opt-in, removing the need for redundant requests & bandwidth usage
* It can reach completion prior to service worker boot up
* Whether the service worker is needed *at all* for a particular request can be determined in advance

But again, I think we need clear data before we do something like this.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/920#issuecomment-229015463

Received on Tuesday, 28 June 2016 10:49:47 UTC