From 1e8b4fe5b0b0e31e9d54c5b479727a9a0089449b Mon Sep 17 00:00:00 2001 From: Philip Walton Date: Fri, 18 Oct 2024 14:54:16 -0700 Subject: [PATCH] Refactor the `stopListening()` function to only run once (#548) * Refactor the stopListening function * Remove the redundant reportedMetricIDs check --- src/onLCP.ts | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/onLCP.ts b/src/onLCP.ts index 2c065a0c..b831119c 100644 --- a/src/onLCP.ts +++ b/src/onLCP.ts @@ -29,8 +29,6 @@ import {LCPMetric, MetricRatingThresholds, ReportOpts} from './types.js'; /** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */ export const LCPThresholds: MetricRatingThresholds = [2500, 4000]; -const reportedMetricIDs: Record = {}; - /** * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and * calls the `callback` function once the value is ready (along with the @@ -84,28 +82,23 @@ export const onLCP = ( opts!.reportAllChanges, ); - // Ensure this logic only runs once, and wrap it in an idle callback - // so the callback is run in a separate task to avoid extending the - // keyboard/click handler to reduce INP impact. - // https://github.com/GoogleChrome/web-vitals/issues/383 - const stopListening = () => - whenIdleOrHidden( - runOnce(() => { - if (!reportedMetricIDs[metric.id]) { - handleEntries(po!.takeRecords() as LCPMetric['entries']); - po!.disconnect(); - reportedMetricIDs[metric.id] = true; - report(true); - } - }), - ); + // Ensure this logic only runs once, since it can be triggered from + // any of three different event listeners below. + const stopListening = runOnce(() => { + handleEntries(po!.takeRecords() as LCPMetric['entries']); + po!.disconnect(); + report(true); + }); // Stop listening after input or visibilitychange. // Note: while scrolling is an input that stops LCP observation, it's // unreliable since it can be programmatically generated. // See: https://github.com/GoogleChrome/web-vitals/issues/75 for (const type of ['keydown', 'click', 'visibilitychange']) { - addEventListener(type, () => stopListening(), { + // Wrap the listener in an idle callback so it's run in a separate + // task to reduce potential INP impact. + // https://github.com/GoogleChrome/web-vitals/issues/383 + addEventListener(type, () => whenIdleOrHidden(stopListening), { capture: true, once: true, }); @@ -124,7 +117,6 @@ export const onLCP = ( doubleRAF(() => { metric.value = performance.now() - event.timeStamp; - reportedMetricIDs[metric.id] = true; report(true); }); });