Skip to content

Commit

Permalink
fix(service-worker): send initialization signal from the application
Browse files Browse the repository at this point in the history
The Service Worker contains a mechanism by which it will postMessage
itself a signal to initialize its caches. Through this mechanism,
initialization happens asynchronously while keeping the SW process
alive.

Unfortunately in Firefox, the SW does not have the ability to
postMessage itself during the activation event. This prevents the
above mechanism from working, and the SW initializes on the next
fetch event, which is often too late.

Therefore, this change has the application wait for SW changes and
tells each new SW to initialize itself. This happens in addition to
the self-signal that the SW attempts to send (as self-signaling is
more reliable). That way even on browsers such as Firefox,
initialization happens eagerly.
  • Loading branch information
alxhub committed Dec 1, 2017
1 parent f841fbe commit 3fbcde9
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/service-worker/src/module.ts
Expand Up @@ -35,6 +35,15 @@ export function ngswAppInitializer(
const isStable = op_take.call(onStable, 1) as Observable<boolean>;
const whenStable = op_toPromise.call(isStable) as Promise<boolean>;

// Wait for service worker controller changes, and fire an INITIALIZE action when a new SW
// becomes active. This allows the SW to initialize itself even if there is no application
// traffic.
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (navigator.serviceWorker.controller !== null) {
navigator.serviceWorker.controller.postMessage({action: 'INITIALIZE'});
}
});

// Don't return the Promise, as that will block the application until the SW is registered, and
// cause a crash if the SW registration fails.
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
Expand Down

0 comments on commit 3fbcde9

Please sign in to comment.