Re: [w3c/ServiceWorker] Provide a way to skipWaiting when the last tab refreshes (#993)

Thrashing around for a way to make this work on Firefox, this trick seems to work, but it seems too clever to be the right thing:

https://github.com/dfabulich/service-worker-refresh-bug/tree/master/fixed-atomic-skip-waiting

1. subresource URLs have a `?v=1` URL parameter to uniquify them. (In production, they'd use hashes instead of version numbers.)
2. Instead of deleting all non-current caches during activate, as all SW tutorials do, we `.slice(0,-2)` the cache key list, deleting all old caches except for the last two. Thus, when the v2 SW skips waiting during install, the existing tab can still access its `?v=1` URLs, but we'll eventually drop the v1 cache when the v3 SW activates.
3. When I did this naively, I'd assumed that `caches.match()` would return `index.html` from the newest cache, but it did the opposite, returning `index.html` from the oldest cache. So the page effectively refused to update at all, relying on the old cache when a new one was available. So I tweaked the `fetch`event handler to first query the current SW's own cache, and then fallback to querying all caches before giving up and hitting the network.
4. That worked for refreshing one tab, but if I opened two or three tabs and tried to push an update, I'd get some tabs on the old version and some tabs on the new version, which is what I said I didn't want. So, for my last trick, we count uncontrolled clients in the `install` event handler, and only skipWaiting if there's exactly one client. This is a big ~hack~ compromise; refreshing the only tab works fine, but if a new SW installs while there are multiple tabs open, it will refuse activate even if you close all other tabs and refresh the last tab.

-- 
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/993#issuecomment-338813359

Received on Monday, 23 October 2017 22:19:22 UTC