-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a way to skipWaiting when the last tab refreshes #1238
Comments
In the meantime, I recommend developers use code like this during the addEventListener('fetch', event => {
event.respondWith((async () => {
if (event.request.mode === "navigate" &&
event.request.method === "GET" &&
registration.waiting &&
(await clients.matchAll()).length < 2
) {
registration.waiting.postMessage('skipWaiting');
return new Response("", {headers: {"Refresh": "0"}});
}
return await caches.match(event.request) ||
fetch(event.request);
})());
}); When doing an ordinary navigation while a |
@dfabulich old thread/comment so things must of changed since you made that suggestion - but that code you posted completely freezes my browser and goes into endless loop when the service worker code is updated and you refresh the page. |
I don't think the code is buggy. Try this sample. https://github.com/dfabulich/service-worker-refresh-sample use the I think you've fallen into a common service worker trap. If you reload on Don't do this in the page: navigator.serviceWorker.addEventListener(`controllerchange`, function (event) {
window.location.reload();
} do this instead var refreshing;
navigator.serviceWorker.addEventListener(`controllerchange`, function (event) {
if (refreshing) return;
refreshing = true;
window.location.reload();
} |
In 2024 this still seems to be an issue, I tried your solution, which works, but has a bug: if you open a new tab with the same link, while a tab is already opened, the service worker catches the navigate event and still think it has only 1 client, since the second one is loading, and therefore skip waiting, even though the first client has not reloaded. This leads to a situation when the first client was loaded using the old sw but now is controlled by the new one, making this solution risky =/ |
When you have a single ("last/only") tab/client controlled by a Service Worker
v1
, and a newv2
Service Worker installs, thev2
SW goes into a "waiting" state. Thev2
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 thev1
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 thev2
SW, and letv2
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, andContent-Disposition: attachment
responses force the browser to just initiate a download without navigating.) That would leave a tab that was loaded inv1
under the control of thev2
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: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.
The text was updated successfully, but these errors were encountered: