-
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
[Proposal] ServiceWorkerContainer.installing(scope) promise #1364
Comments
|
@jeffposnick @jakearchibald @dfabulich PTAL. Please help fix (work around) the problems mentioned above in my web component. |
I think I'd need to see more clarity in the "Motivation" section. At a minimum, I have these questions:
But let's suppose you say "Very well, I now see that I didn't really want this to be a WC at all; I really just wanted to prolyfill Per #1247 I think you can do what you want with code like this: 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);
});
}
navigator.serviceWorker.register('/sw.js').then(function(reg) {
listenForStateChanges(reg);
}); But, again, if you're just using code like this for performance logging and/or error tracking, I recommend not doing this at all. Just put your tracking code in the SW script. "But what if the SW script fails?" Feel free to track registration failures when you call |
Motivation
I'm developing a web component to observe the whole service workers lifecycle. Something like:
Valid values of
registration-state
property (attribute) areinstalling
,waiting
andactive
.Valid values of
state
property (attribute) areinstalling
,installed
,activating
,activated
andredundant
.When the user inserts this custom HTML element into the page, it finds the service worker, updates its properties (attributes) and creates custom events. The user can listen to these events and e.g. show popups when the service worker has been installed for the first time ("Content is now available offline") or the new service worker has been installed, replacing the current service worker ("New or updated content is available"), etc.
The first idea that came to my mind was to use
ready
promise:The good thing about
ready
promise is it will never reject, and waits indefinitely until theServiceWorkerRegistration
associated with the current page has anactive
worker.But this is a bad idea.
Problems
ready
promise resolves to the registration when the state isactivating
oractivated
. This means it's not possible to getinstalling
andinstalled
states. So it's not possible to show popups when the service worker has been installed for the first time or the new service worker has been installed, replacing the current service worker.ready
doesn't have thescope
parameter. What if the web app has multiple service workers and I need to get the service worker with a certain scope?The next idea was to use
getRegistration()
method.The good thing about
getRegistration()
promise is it has thescope
parameter.But it also has problems.
Problems
getRegistration()
dosn't wait indefinitely (likeready
). It can resolves toundefined
(ifgetRegistration()
is called beforeregister()
). That means I need to find the right moment to callgetRegistration()
. If I call it too soon, I will getundefined
. If I call it too late, I may missinstalling
/installed
/activating
states.The good practice is to use the window load event to register service worker (to keep the page load performant):
But it doesn't mean that everyone is doing it.
The first thing I did in my web component was to place
getRegistration()
insideconnectedCallback
lifecycle callback:Here are the problems I encountered:
Problems
If the registered service worker doesn't use the window load event, there are 2 options:
connectedCallback
(andgetRegistration()
) is called beforeregister()
, I will getundefined
.register()
is called beforeconnectedCallback
(andgetRegistration()
), I may miss some ofinstalling
/installed
/activating
states.The next idea was to use the window load event to call
getRegistration()
insideconnectedCallback
lifecycle callback (it should fix the case whengetRegistration()
is called before the window load event (and beforeregister()
):But this is also a bad idea:
Problems
register()
will be called before thegetRegistration()
. Both use the window load event.connectedCallback
will be called afterwindow.onload
. But the code insideconnectedCallback
waits the window load event. This means that the code insideconnectedCallback
will not execute.There is also a case when the web app has a service worker (for precaching static content) [with scope
/
] and the second service worker (for receiving push notifications) [with the different scope] downloads from CDN and registers dynamically later (after the user gives permission to receive push notifications). This is how e.g. Firebase Notifications works (@gauntface knows).The user of my web component may want to observe the whole lifecycle of this lazy-loaded service workers (starting from
installing
state). But it seems that at the moment it's impossible. If I'm wrong, please correct me.Proposal
A new (similar to
ready
) promisenavigator.serviceWorker.installing(scope)
that will never reject, waits indefinitely and resolves to the registration when the state isinstalling
. Also it should have the optionalscope
parameter.In the future, it would be great to have a methods, based on observables instead of promises. The biggest difference between promises and observables is that an observable can receive multiple values over time while a promise only represents a single value (when an async operation completes or fails). I.e. a promise represents a single future event, an observable represents a stream of future events. It should solve the problem with multiple dynamically (at any time) registered service workers. E.g. an observable-based method that returns a (changing over time) array of registrations / service workers.
The text was updated successfully, but these errors were encountered: