Re: [w3c/ServiceWorker] Proposal: Allow addEventListener/removeEventListener for 'fetch' to called at anytime (#1195)

@bgirard 

> Before we discuss adding a new API I'd really like to have an explicit public discussion ruling out this proposal.

I'd rather we sorted out the requirements before we started bikeshedding an API, but ok. Consider:

```js
function fetchHandler() {
  // …
}

addEventListener('fetch', fetchHandler);
```

How are you going to remove that event listener? I guess it's not too hard if you want to remove it from the activate event:

```js
addEventListener('activate', event => {
  event.waitUntil(async function() {
    if (await shouldRemoveFetchListener()) {
      removeEventListener('fetch', fetchHandler);
    }
  }());
});
```

But what if you want to remove it from the page? I guess you'd have to use `postMessage`:

```js
// In the page:
navigator.serviceWorker.controller.postMessage('add-fetch-event');
```

```js
// In the service worker:
addEventListener('message', ({ data }) => {
  if (data == 'add-fetch-event') {
    addEventListener('fetch', fetchHandler);
  }
  else if (data == 'remove-fetch-event') {
    removeEventListener('fetch', fetchHandler);
  }
});
```

If you want to know when that action is complete, I guess you'd have to post a message back. What if you wanted to find out the current state of the event listening? I guess you'll have to store that data in IDB and hope you keep it in sync.

But what if you have one of these?

```js
addEventListener('push', event => …);
```

Or what if you do this?

```js
// In the page:
navigator.serviceWorker.controller.postMessage('do-something');
```

If the service worker isn't running, either of the above will cause it to run. And as it runs it'll come to this line again:

```js
addEventListener('fetch', fetchHandler);
```

And you've added your fetch listener again. Although if the service worker was already running, it wouldn't re-execute right now, so the outcome is time dependent.

Something like `serviceWorker.fetch.disable()` or `swRegistration.fetch.disable()` doesn't have any of these problems. The state is entirely independent of service worker execution, and the API is available from the page so you don't need to hack around with `postMessage` to change state.

Putting it on `serviceWorker` rather than `swRegistration` means it would reset when the service worker updates. Depending on use-cases, that may be a good or bad thing.

Changing navigation preload into a general preload may solve this particular problem, but it also may solve some other issues, such as speeding up stale-while-revalidate type of behaviours.

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

Received on Monday, 25 September 2017 19:00:00 UTC