From 29e8a64cf02fa9b80d38c30091e0b730403c54c8 Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Tue, 24 Mar 2020 22:54:53 +0200 Subject: [PATCH] fix(service-worker): by default register the SW after 30s even the app never stabilizes (#35870) Previously, when using the default ServiceWorker registration strategy Angular would wait indefinitely for the [app to stabilize][1], before registering the ServiceWorker script. This could lead to a situation where the ServiceWorker would never be registered when there was a long-running task (such as an interval or recurring timeout). Such tasks can often be started by a 3rd-party dependency (beyond the developer's control or even without them realizing). In addition, this situation is particularly hard to detect, because the ServiceWorker is typically not used during development and on production builds a previous ServiceWorker instance might be already active. This commit fixes this by changing the default registration strategy from `registerWhenStable` to `registerWhenStable:30000`, which will ensure that the ServiceWorker will be registered after 30s at the latest, even if the app has not stabilized by then. Fixes #34464 PR Close #35870 --- packages/service-worker/src/module.ts | 4 +++- packages/service-worker/test/module_spec.ts | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/service-worker/src/module.ts b/packages/service-worker/src/module.ts index 7e7779f5d7..85eef4f67c 100644 --- a/packages/service-worker/src/module.ts +++ b/packages/service-worker/src/module.ts @@ -100,7 +100,9 @@ export function ngswAppInitializer( if (typeof options.registrationStrategy === 'function') { readyToRegister$ = options.registrationStrategy(); } else { - const [strategy, ...args] = (options.registrationStrategy || 'registerWhenStable').split(':'); + const [strategy, ...args] = + (options.registrationStrategy || 'registerWhenStable:30000').split(':'); + switch (strategy) { case 'registerImmediately': readyToRegister$ = of (null); diff --git a/packages/service-worker/test/module_spec.ts b/packages/service-worker/test/module_spec.ts index 46591e100f..2f6d8a3768 100644 --- a/packages/service-worker/test/module_spec.ts +++ b/packages/service-worker/test/module_spec.ts @@ -147,7 +147,7 @@ describe('ServiceWorkerModule', () => { return isStableSub; }; - it('defaults to registering the SW when the app stabilizes', fakeAsync(() => { + it('defaults to registering the SW when the app stabilizes (under 30s)', fakeAsync(() => { const isStableSub = configTestBedWithMockedStability(); isStableSub.next(false); @@ -156,7 +156,7 @@ describe('ServiceWorkerModule', () => { tick(); expect(swRegisterSpy).not.toHaveBeenCalled(); - tick(60000); + tick(20000); expect(swRegisterSpy).not.toHaveBeenCalled(); isStableSub.next(true); @@ -165,6 +165,17 @@ describe('ServiceWorkerModule', () => { expect(swRegisterSpy).toHaveBeenCalledWith('sw.js', {scope: undefined}); })); + it('defaults to registering the SW after 30s if the app does not stabilize sooner', + fakeAsync(() => { + const isStableSub = configTestBedWithMockedStability(); + + tick(29999); + expect(swRegisterSpy).not.toHaveBeenCalled(); + + tick(1); + expect(swRegisterSpy).toHaveBeenCalledWith('sw.js', {scope: undefined}); + })); + it('registers the SW when the app stabilizes with `registerWhenStable:`', fakeAsync(() => { const isStableSub = configTestBedWithMockedStability('registerWhenStable:1000');