Skip to content

Commit 432390b

Browse files
committed
fix(browser-utils): Ensure web vital client hooks unsubscribe correctly
1 parent eda7e33 commit 432390b

File tree

1 file changed

+11
-3
lines changed
  • packages/browser-utils/src/metrics

1 file changed

+11
-3
lines changed

packages/browser-utils/src/metrics/utils.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,21 @@ export function listenForWebVitalReportEvents(
226226
// we only want to collect LCP if we actually navigate. Redirects should be ignored.
227227
if (!options?.isRedirect) {
228228
_runCollectorCallbackOnce('navigation');
229-
unsubscribeStartNavigation?.();
230-
unsubscribeAfterStartPageLoadSpan?.();
229+
safeUnsubscribe(unsubscribeStartNavigation, unsubscribeAfterStartPageLoadSpan);
231230
}
232231
});
233232

234233
const unsubscribeAfterStartPageLoadSpan = client.on('afterStartPageLoadSpan', span => {
235234
pageloadSpanId = span.spanContext().spanId;
236-
unsubscribeAfterStartPageLoadSpan?.();
235+
safeUnsubscribe(unsubscribeAfterStartPageLoadSpan);
237236
});
238237
}
238+
239+
/**
240+
* Invoke a list of unsubscribers in a safe way, by deferring the invocation to the next tick.
241+
* This is necessary because unsubscribing in sync can lead to other callbacks no longer being invoked
242+
* due to in-place array mutation of the subscribers array on the client.
243+
*/
244+
function safeUnsubscribe(...unsubscribers: (() => void | undefined)[]): void {
245+
unsubscribers.forEach(u => u && setTimeout(u, 0));
246+
}

0 commit comments

Comments
 (0)