Provide a way to skipWaiting when the last tab refreshes
Nobody has claimed this yet.
- Dominant language
- Bikeshed
- Stars
- 3.6k
- Forks
- 324
- Avg merge
- 14d 22h
- Merged PRs (30d)
- 1
Description
When you have a single ("last/only") tab/client controlled by a Service Worker v1, and a new v2 Service Worker installs, the v2 SW goes into a "waiting" state. The v2 SW activates when the last client closes.
Surprisingly, the v2 Service Worker doesn't activate when the last client refreshes/navigates to a new page, because the navigation request initiates while the last/only tab is still open, so the v1 Service Worker handles it; I think many developers don't realize that navigation requests start that early.
If we wanted to mitigate the surprise, the "obvious" thing to do would be to always delay the navigation request when there's a v2 Service Worker waiting, activate the v2 SW, and let v2 control the navigation request instead.
But there's a problem. There are some HTTP responses that can cause the browser to cancel the navigation. (I know of two such cases: 204 No Content responses have null bodies and prevent navigation, and Content-Disposition: attachment responses force the browser to just initiate a download without navigating.) That would leave a tab that was loaded in v1 under the control of the v2 Service Worker, which may be unsafe.
What I'd like is a way of expressing to the Service Worker lifecycle that I know it's safe for the v2 Service Worker to activate when the last/only client navigates.
Jake suggested a navigation event listener, like this:
self.addEventListener('navigation', event => {
if (registration.waiting) {
event.waitUntil(
clients.matchAll().then(clients => {
if (clients.length < 2) {
return registration.waiting.skipWaiting();
}
})
);
}
});
The navigation would be delayed until the waiting worker activates, so the navigation request would go through the new worker.
That'd be really nice.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Service Worker lifecycle discussion in this issue, especially the proposed navigation event listener and registration.waiting.skipWaiting() flow. Determine whether a waiting worker can safely activate during a last-client navigation without mishandling cancelled navigations such as 204 or attachment responses; done means an agreed and specified lifecycle behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- api, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100