fix(service-worker): prevent duplicate fetches during concurrent update checks (#61443)

Previously, multiple simultaneous calls to `checkForUpdate()` could result in redundant
fetches and hashing of the update manifest, leading to unnecessary network and CPU usage.

This change introduces a mechanism to track an in-progress update check using a cached
promise (`ongoingCheckForUpdate`). Subsequent calls to `checkForUpdate()` while a check
is in progress will return the same promise instead of triggering a new request.

Once the check completes (successfully or not), the cached promise is cleared,
allowing future update checks to proceed normally.

This improves efficiency and prevents overlapping update logic in applications that
may invoke `checkForUpdate()` from multiple sources (e.g. polling, manual triggers).

PR Close #61443
This commit is contained in:
arturovt
2025-05-17 01:25:04 +03:00
committed by kirjs
parent c67dbda8ff
commit 6adf022f0d
+11 -1
View File
@@ -53,6 +53,8 @@ export class SwUpdate {
return this.sw.isEnabled;
}
private ongoingCheckForUpdate: Promise<boolean> | null = null;
constructor(private sw: NgswCommChannel) {
if (!sw.isEnabled) {
this.versionUpdates = NEVER;
@@ -81,8 +83,16 @@ export class SwUpdate {
if (!this.sw.isEnabled) {
return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED));
}
if (this.ongoingCheckForUpdate) {
return this.ongoingCheckForUpdate;
}
const nonce = this.sw.generateNonce();
return this.sw.postMessageWithOperation('CHECK_FOR_UPDATES', {nonce}, nonce);
this.ongoingCheckForUpdate = this.sw
.postMessageWithOperation('CHECK_FOR_UPDATES', {nonce}, nonce)
.finally(() => {
this.ongoingCheckForUpdate = null;
});
return this.ongoingCheckForUpdate;
}
/**