Skip to content
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 an easier way to listen for waiting/activated/redundant Service Workers #1247

Open
dfabulich opened this issue Dec 14, 2017 · 6 comments

Comments

@dfabulich
Copy link

dfabulich commented Dec 14, 2017

Breaking off from #1222.

ServiceWorker.state has five states: installing, installed (waiting), activating, activated, and redundant.

Today, client-side code can listen for installing SWs with ServiceWorkerRegistration.onupdatefound; activating can be tracked with navigator.serviceWorker.oncontrollerchange.

The other three states are annoying to listen for.

function listenForStateChanges(reg, callback) {
  if (reg.installing) reg.installing.addEventListener('statechange', callback);
  if (reg.waiting) reg.waiting.addEventListener('statechange', callback);
  reg.addEventListener('updatefound', function() {
    reg.installing.addEventListener('statechange', callback);
  });
}

That's too bad, because lots of users want to track the installed state so they can show a refresh banner. Furthermore, some users apparently want to track redundant SWs for error handling. And it turns out that refreshing the page as the page is activating is slightly too soon; you should wait for the activated event, to avoid a minor performance bug.

In #1222 we observed that awaiting these states would be way easier if statechange bubbled up to the registration, so users who wanted to track the redundant and activated states would just do this:

reg.addEventListener('statechange', callback);
@dfabulich
Copy link
Author

dfabulich commented Dec 14, 2017

Alerting users of a waiting service worker might look like this:

Combined with #1016, that means that showing a "please refresh" banner could work like this:

function alertUser(reg) {
  // don't use confirm in production; this is just an example
  if (confirm('Refresh now?')) reg.waiting.skipWaiting();
}

if (reg.waiting) alertUser(reg);
reg.addEventListener('statechange', function(e) {
  if (e.target.state === 'installed') {
    alertUser(reg);
  } else if (e.target.state === 'activated') {
    window.location.reload();
  }
});

@dfabulich dfabulich changed the title Provide an easier way to listen for waiting/activating/redundant Service Workers Provide an easier way to listen for waiting/activated/redundant Service Workers Dec 14, 2017
@ouksal
Copy link

ouksal commented Feb 13, 2019

@dfabulich I like your suggestion. I can't believe nobody has been assigned to fix this!

@jakearchibald
Copy link
Contributor

A promise doesn't really work in this case, as many service workers can pass through the waiting phase during the life of a page.

@dfabulich
Copy link
Author

To be clear, this issue #1247 doesn't involve Promises; it calls for the statechange event to bubble up to the registration. Issue #1222 recommends a Promise; I'll copy and paste your comment there.

@dfabulich
Copy link
Author

In fact, this issue was originally @jakearchibald's idea, in a comment on #1222.

As far as I can tell, nobody has had anything bad to say about it. I might have preferred #1222, but since that approach seems to be dead in the water, this is still a big improvement over the status quo.

@daffinm
Copy link

daffinm commented Apr 3, 2020

+1 for @dfabulich prolyfil idea. 3 years old and still needed IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants