fix(service-worker): clean up caches from old SW versions (#26319)
Since the SW immediately takes over all clients, it is safe to delete caches used by older (e.g. beta) `@angular/service-worker` versions to avoid running into browser storage quota limitations. PR Close #26319
This commit is contained in:

committed by
Miško Hevery

parent
41de0e0d98
commit
2326b9c294
@ -123,9 +123,22 @@ export class Driver implements Debuggable, UpdateSource {
|
||||
// The activate event is triggered when this version of the service worker is
|
||||
// first activated.
|
||||
this.scope.addEventListener('activate', (event) => {
|
||||
// As above, it's safe to take over from existing clients immediately, since
|
||||
// the new SW version will continue to serve the old application.
|
||||
event !.waitUntil(this.scope.clients.claim());
|
||||
event !.waitUntil((async() => {
|
||||
// As above, it's safe to take over from existing clients immediately, since the new SW
|
||||
// version will continue to serve the old application.
|
||||
await this.scope.clients.claim();
|
||||
|
||||
// Once all clients have been taken over, we can delete caches used by old versions of
|
||||
// `@angular/service-worker`, which are no longer needed. This can happen in the background.
|
||||
this.idle.schedule('activate: cleanup-old-sw-caches', async() => {
|
||||
try {
|
||||
await this.cleanupOldSwCaches();
|
||||
} catch (err) {
|
||||
// Nothing to do - cleanup failed. Just log it.
|
||||
this.debugger.log(err, 'cleanupOldSwCaches @ activate: cleanup-old-sw-caches');
|
||||
}
|
||||
});
|
||||
})());
|
||||
|
||||
// Rather than wait for the first fetch event, which may not arrive until
|
||||
// the next time the application is loaded, the SW takes advantage of the
|
||||
@ -872,6 +885,19 @@ export class Driver implements Debuggable, UpdateSource {
|
||||
await this.sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete caches that were used by older versions of `@angular/service-worker` to avoid running
|
||||
* into storage quota limitations imposed by browsers.
|
||||
* (Since at this point the SW has claimed all clients, it is safe to remove those caches.)
|
||||
*/
|
||||
async cleanupOldSwCaches(): Promise<void> {
|
||||
const cacheNames = await this.scope.caches.keys();
|
||||
const oldSwCacheNames =
|
||||
cacheNames.filter(name => /^ngsw:(?:active|staged|manifest:.+)$/.test(name));
|
||||
|
||||
await Promise.all(oldSwCacheNames.map(name => this.scope.caches.delete(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a specific version of the given resource is cached anywhere within the SW,
|
||||
* and fetch it if so.
|
||||
|
Reference in New Issue
Block a user