fix(service-worker): prevent SW registration strategies from affecting app stabilization (#35870)
Previously, some of the built-in ServiceWorker registration strategies, namely `registerWithDelay:<timeout>` and `registerWhenStable:<timeout>`, would register potentially long-running timeout, thus preventing the app from stabilizing before the timeouts expired. This was especially problematic for the `registerWhenStable:<timeout>` strategy, which waits for the app to stabilize, because the strategy itself would prevent the app from stabilizing and thus the ServiceWorker would always be registered after the timeout. This commit fixes this by subscribing to the registration strategy observable outside the Angular zone, thus not affecting the app's stabilization. PR Close #35870
This commit is contained in:
parent
29e8a64cf0
commit
2d7c95fb70
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {isPlatformBrowser} from '@angular/common';
|
||||
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
|
||||
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, NgZone, PLATFORM_ID} from '@angular/core';
|
||||
import {Observable, merge, of } from 'rxjs';
|
||||
import {delay, filter, take} from 'rxjs/operators';
|
||||
|
||||
|
@ -122,10 +122,15 @@ export function ngswAppInitializer(
|
|||
}
|
||||
|
||||
// Don't return anything to avoid blocking the application until the SW is registered.
|
||||
// Also, run outside the Angular zone to avoid preventing the app from stabilizing (especially
|
||||
// given that some registration strategies wait for the app to stabilize).
|
||||
// Catch and log the error if SW registration fails to avoid uncaught rejection warning.
|
||||
readyToRegister$.pipe(take(1)).subscribe(
|
||||
() => navigator.serviceWorker.register(script, {scope: options.scope})
|
||||
.catch(err => console.error('Service worker registration failed with:', err)));
|
||||
const ngZone = injector.get(NgZone);
|
||||
ngZone.runOutsideAngular(
|
||||
() => readyToRegister$.pipe(take(1)).subscribe(
|
||||
() =>
|
||||
navigator.serviceWorker.register(script, {scope: options.scope})
|
||||
.catch(err => console.error('Service worker registration failed with:', err))));
|
||||
};
|
||||
return initializer;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue