Skip to content

Commit 6bf07b4

Browse files
committed
fix(service-worker): send initialization signal from the application
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.
1 parent a2ff4ab commit 6bf07b4

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

packages/service-worker/src/module.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ export function ngswAppInitializer(
3535
const isStable = op_take.call(onStable, 1) as Observable<boolean>;
3636
const whenStable = op_toPromise.call(isStable) as Promise<boolean>;
3737

38+
// Wait for service worker controller changes, and fire an INITIALIZE action when a new SW
39+
// becomes active. This allows the SW to initialize itself even if there is no application
40+
// traffic.
41+
navigator.serviceWorker.addEventListener('controllerchange', () => {
42+
if (navigator.serviceWorker.controller !== null) {
43+
navigator.serviceWorker.controller.postMessage({action: 'INITIALIZE'});
44+
}
45+
});
46+
3847
// Don't return the Promise, as that will block the application until the SW is registered, and
3948
// cause a crash if the SW registration fails.
4049
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));

0 commit comments

Comments
 (0)