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
This commit is contained in:
Sonu Kapoor 2020-03-24 22:54:53 +02:00 committed by Alex Rickabaugh
parent 00efacf561
commit 29e8a64cf0
2 changed files with 16 additions and 3 deletions

View File

@ -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);

View File

@ -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:<timeout>`',
fakeAsync(() => {
const isStableSub = configTestBedWithMockedStability('registerWhenStable:1000');