web-vitals
Version:
Easily measure performance metrics in JavaScript
1 lines • 84.6 kB
Source Map (JSON)
{"version":3,"file":"web-vitals.umd.cjs","sources":["modules/lib/bfcache.js","modules/lib/bindReporter.js","modules/lib/doubleRAF.js","modules/lib/getNavigationEntry.js","modules/lib/getActivationStart.js","modules/lib/getVisibilityWatcher.js","modules/lib/initMetric.js","modules/lib/generateUniqueID.js","modules/lib/initUnique.js","modules/lib/LayoutShiftManager.js","modules/lib/observe.js","modules/lib/softNavs.js","modules/lib/runOnce.js","modules/lib/FCPEntryManager.js","modules/lib/whenActivated.js","modules/onFCP.js","modules/onCLS.js","modules/lib/polyfills/interactionCountPolyfill.js","modules/lib/InteractionManager.js","modules/lib/whenIdleOrHidden.js","modules/onINP.js","modules/lib/LCPEntryManager.js","modules/onLCP.js","modules/onTTFB.js"],"sourcesContent":["/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nlet bfcacheRestoreTime = -1;\nexport const getBFCacheRestoreTime = () => bfcacheRestoreTime;\nexport const onBFCacheRestore = (cb) => {\n addEventListener('pageshow', (event) => {\n if (event.persisted) {\n bfcacheRestoreTime = event.timeStamp;\n cb(event);\n }\n }, true);\n};\n//# sourceMappingURL=bfcache.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst getRating = (value, thresholds) => {\n if (value > thresholds[1]) {\n return 'poor';\n }\n if (value > thresholds[0]) {\n return 'needs-improvement';\n }\n return 'good';\n};\nexport const bindReporter = (callback, metric, thresholds, reportAllChanges) => {\n let prevValue;\n let delta;\n return (forceReport) => {\n if (metric.value >= 0) {\n if (forceReport || reportAllChanges) {\n delta = metric.value - (prevValue ?? 0);\n // Report the metric if there's a non-zero delta or if no previous\n // value exists (which can happen in the case of the document becoming\n // hidden when the metric value is 0).\n // See: https://github.com/GoogleChrome/web-vitals/issues/14\n if (delta || prevValue === undefined) {\n prevValue = metric.value;\n metric.delta = delta;\n metric.rating = getRating(metric.value, thresholds);\n callback(metric);\n }\n }\n }\n };\n};\n//# sourceMappingURL=bindReporter.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const doubleRAF = (cb) => {\n requestAnimationFrame(() => requestAnimationFrame(() => cb()));\n};\n//# sourceMappingURL=doubleRAF.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const getNavigationEntry = () => {\n const navigationEntry = performance.getEntriesByType('navigation')[0];\n // Check to ensure the `responseStart` property is present and valid.\n // In some cases a zero value is reported by the browser (for\n // privacy/security reasons), and in other cases (bugs) the value is\n // negative or is larger than the current page time. Ignore these cases:\n // - https://github.com/GoogleChrome/web-vitals/issues/137\n // - https://github.com/GoogleChrome/web-vitals/issues/162\n // - https://github.com/GoogleChrome/web-vitals/issues/275\n if (navigationEntry &&\n navigationEntry.responseStart > 0 &&\n navigationEntry.responseStart < performance.now()) {\n return navigationEntry;\n }\n};\n//# sourceMappingURL=getNavigationEntry.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getNavigationEntry } from './getNavigationEntry.js';\nexport const getActivationStart = () => {\n return getNavigationEntry()?.activationStart ?? 0;\n};\n//# sourceMappingURL=getActivationStart.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { onBFCacheRestore } from './bfcache.js';\nimport { getActivationStart } from './getActivationStart.js';\nlet firstHiddenTime = -1;\nconst onHiddenFunctions = new Set();\nconst initHiddenTime = () => {\n // If the document is hidden when this code runs, assume it was always\n // hidden and the page was loaded in the background, with the one exception\n // that visibility state is always 'hidden' during prerendering, so we have\n // to ignore that case until prerendering finishes (see: `prerenderingchange`\n // event logic below).\n return document.visibilityState === 'hidden' && !document.prerendering\n ? 0\n : Infinity;\n};\nconst onVisibilityUpdate = (event) => {\n // Handle changes to hidden state\n if (document.visibilityState === 'hidden') {\n if (event.type === 'visibilitychange') {\n for (const onHiddenFunction of onHiddenFunctions) {\n onHiddenFunction();\n }\n }\n // If the document is 'hidden' and no previous hidden timestamp has been\n // set (so is infinity), update it based on the current event data.\n if (!isFinite(firstHiddenTime)) {\n // If the event is a 'visibilitychange' event, it means the page was\n // visible prior to this change, so the event timestamp is the first\n // hidden time.\n // However, if the event is not a 'visibilitychange' event, then it must\n // be a 'prerenderingchange' event, and the fact that the document is\n // still 'hidden' from the above check means the tab was activated\n // in a background state and so has always been hidden.\n firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;\n // We no longer need the `prerenderingchange` event listener now we've\n // set an initial init time so remove that\n // (we'll keep the visibilitychange one for onHiddenFunction above)\n removeEventListener('prerenderingchange', onVisibilityUpdate, true);\n }\n }\n};\nexport const getVisibilityWatcher = (reset = false) => {\n if (reset) {\n firstHiddenTime = Infinity;\n }\n if (firstHiddenTime < 0) {\n // Check if we have a previous hidden `visibility-state` performance entry.\n const activationStart = getActivationStart();\n /* eslint-disable indent */\n const firstVisibilityStateHiddenTime = !document.prerendering\n ? globalThis.performance\n .getEntriesByType('visibility-state')\n .find((e) => e.name === 'hidden' && e.startTime >= activationStart)\n ?.startTime\n : undefined;\n /* eslint-enable indent */\n // Prefer that, but if it's not available and the document is hidden when\n // this code runs, assume it was hidden since navigation start. This isn't\n // a perfect heuristic, but it's the best we can do until the\n // `visibility-state` performance entry becomes available in all browsers.\n firstHiddenTime = firstVisibilityStateHiddenTime ?? initHiddenTime();\n // Listen for visibility changes so we can handle things like bfcache\n // restores and/or prerender without having to examine individual\n // timestamps in detail and also for onHidden function calls.\n addEventListener('visibilitychange', onVisibilityUpdate, true);\n // IMPORTANT: when a page is prerendering, its `visibilityState` is\n // 'hidden', so in order to account for cases where this module checks for\n // visibility during prerendering, an additional check after prerendering\n // completes is also required.\n addEventListener('prerenderingchange', onVisibilityUpdate, true);\n // Reset the time on bfcache restores.\n onBFCacheRestore(() => {\n // Schedule a task in order to track the `visibilityState` once it's\n // had an opportunity to change to visible in all browsers.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1133363\n setTimeout(() => {\n firstHiddenTime = initHiddenTime();\n });\n });\n }\n return {\n get firstHiddenTime() {\n return firstHiddenTime;\n },\n onHidden(cb) {\n onHiddenFunctions.add(cb);\n },\n };\n};\n//# sourceMappingURL=getVisibilityWatcher.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getBFCacheRestoreTime } from './bfcache.js';\nimport { generateUniqueID } from './generateUniqueID.js';\nimport { getActivationStart } from './getActivationStart.js';\nimport { getNavigationEntry } from './getNavigationEntry.js';\nexport const initMetric = (name, value = -1, navigationType, navigationId = 0, navigationInteractionId, navigationURL, navigationStartTime) => {\n const hardNavEntry = getNavigationEntry();\n const hardNavId = hardNavEntry?.navigationId || 0;\n let _navigationType = 'navigate';\n if (navigationType) {\n // If it was passed in, then use that\n _navigationType = navigationType;\n }\n else if (getBFCacheRestoreTime() >= 0) {\n _navigationType = 'back-forward-cache';\n }\n else if (hardNavEntry) {\n if (document.prerendering || getActivationStart() > 0) {\n _navigationType = 'prerender';\n }\n else if (document.wasDiscarded) {\n _navigationType = 'restore';\n }\n else if (hardNavEntry.type) {\n _navigationType = hardNavEntry.type.replace(/_/g, '-');\n }\n }\n // Use `entries` type specific for the metric.\n const entries = [];\n return {\n name,\n value,\n rating: 'good', // If needed, will be updated when reported. `const` to keep the type from widening to `string`.\n delta: 0,\n entries,\n id: generateUniqueID(),\n navigationType: _navigationType,\n navigationId: navigationId || hardNavId,\n navigationInteractionId: navigationInteractionId,\n navigationURL: navigationURL || hardNavEntry?.name,\n navigationStartTime: navigationStartTime || 0,\n };\n};\n//# sourceMappingURL=initMetric.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Performantly generate a unique, 30-char string by combining a version\n * number, the current timestamp with a 13-digit number integer.\n * @return {string}\n */\nexport const generateUniqueID = () => {\n return `v6-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;\n};\n//# sourceMappingURL=generateUniqueID.js.map","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst instanceMap = new WeakMap();\n/**\n * A function that accepts and identity object and a class object and returns\n * either a new instance of that class or an existing instance, if the\n * identity object was previously used.\n */\nexport function initUnique(identityObj, ClassObj) {\n let classInstances = instanceMap.get(ClassObj);\n if (!classInstances) {\n classInstances = new WeakMap();\n instanceMap.set(ClassObj, classInstances);\n }\n if (!classInstances.get(identityObj)) {\n classInstances.set(identityObj, new ClassObj());\n }\n return classInstances.get(identityObj);\n}\n//# sourceMappingURL=initUnique.js.map","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport class LayoutShiftManager {\n _onAfterProcessingUnexpectedShift;\n _sessionValue = 0;\n _sessionEntries = [];\n _processEntry(entry) {\n // Only count layout shifts without recent user input.\n if (entry.hadRecentInput)\n return;\n const firstSessionEntry = this._sessionEntries[0];\n const lastSessionEntry = this._sessionEntries.at(-1);\n // If the entry occurred less than 1 second after the previous entry\n // and less than 5 seconds after the first entry in the session,\n // include the entry in the current session. Otherwise, start a new\n // session.\n if (this._sessionValue &&\n firstSessionEntry &&\n lastSessionEntry &&\n entry.startTime - lastSessionEntry.startTime < 1000 &&\n entry.startTime - firstSessionEntry.startTime < 5000) {\n this._sessionValue += entry.value;\n this._sessionEntries.push(entry);\n }\n else {\n this._sessionValue = entry.value;\n this._sessionEntries = [entry];\n }\n this._onAfterProcessingUnexpectedShift?.(entry);\n }\n}\n//# sourceMappingURL=LayoutShiftManager.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Takes a performance entry type and a callback function, and creates a\n * `PerformanceObserver` instance that will observe the specified entry type\n * with buffering enabled and call the callback _for each entry_.\n *\n * This function also feature-detects entry support and wraps the logic in a\n * try/catch to avoid errors in unsupporting browsers.\n */\nexport const observe = (types, callback, opts = {}) => {\n try {\n const supportedTypes = types.filter((t) => PerformanceObserver.supportedEntryTypes.includes(t));\n if (supportedTypes.length > 0) {\n const po = new PerformanceObserver((list) => {\n // Delay by a microtask to workaround a bug in Safari where the\n // callback is invoked immediately, rather than in a separate task.\n // See: https://github.com/GoogleChrome/web-vitals/issues/277\n queueMicrotask(() => {\n const entries = list.getEntries();\n // When observing more than one entry type, entries from different\n // types can be delivered out of order, so sort by end time\n // (startTime + duration) to ensure they're in the right order.\n // See: https://github.com/w3c/performance-timeline/issues/224\n if (supportedTypes.length > 1) {\n entries.sort((a, b) => {\n const scoreA = a.startTime + a.duration;\n const scoreB = b.startTime + b.duration;\n return scoreA - scoreB;\n });\n }\n callback(entries);\n });\n });\n for (const t of supportedTypes) {\n po.observe({ type: t, buffered: true, ...opts });\n }\n return po;\n }\n }\n catch {\n // Do nothing.\n }\n return;\n};\n//# sourceMappingURL=observe.js.map","/*\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const checkSoftNavsEnabled = (opts) => {\n return (\n // Firefox has a preference to disable this, which some people use so add a guard\n globalThis.PerformanceObserver?.supportedEntryTypes?.includes('soft-navigation') &&\n // Older implementations expose the value as an attribute rather than the\n // method. We only support the newer method as that was what was launched\n // to stable unflagged.\n typeof globalThis.PerformanceSoftNavigation?.prototype\n ?.getLargestInteractionContentfulPaint === 'function' &&\n opts &&\n opts.reportSoftNavs);\n};\n// Stores a soft navigation entry keyed by its navigationId, keeping only\n// the 2 most recent entries so the map cannot grow unbounded.\nexport const storeSoftNavEntry = (map, entry) => {\n map.set(entry.navigationId, entry);\n // Clean up older entries to prevent memory leaks, keeping only\n // the 2 most recent entries.\n if (map.size > 2) {\n const firstKey = map.keys().next().value;\n if (firstKey !== undefined) {\n map.delete(firstKey);\n }\n }\n};\n//# sourceMappingURL=softNavs.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const runOnce = (cb) => {\n let called = false;\n return () => {\n if (!called) {\n cb();\n called = true;\n }\n };\n};\n//# sourceMappingURL=runOnce.js.map","/*\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport class FCPEntryManager {\n _softNavigationEntryMap;\n}\n//# sourceMappingURL=FCPEntryManager.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const whenActivated = (callback) => {\n if (document.prerendering) {\n addEventListener('prerenderingchange', callback, true);\n }\n else {\n callback();\n }\n};\n//# sourceMappingURL=whenActivated.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { bindReporter } from './lib/bindReporter.js';\nimport { checkSoftNavsEnabled, storeSoftNavEntry } from './lib/softNavs.js';\nimport { doubleRAF } from './lib/doubleRAF.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { initUnique } from './lib/initUnique.js';\nimport { FCPEntryManager } from './lib/FCPEntryManager.js';\nimport { observe } from './lib/observe.js';\nimport { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';\nimport { whenActivated } from './lib/whenActivated.js';\n/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */\nexport const FCPThresholds = [1800, 3000];\n/**\n * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `paint` performance entry used to determine the value. The reported\n * value is a `DOMHighResTimeStamp`.\n */\nexport const onFCP = (onReport, opts = {}) => {\n const softNavsEnabled = checkSoftNavsEnabled(opts);\n whenActivated(() => {\n // Create a new FCP entry manager for each page activation\n // This allows us to track soft navigations separately\n // needed when attribution is enabled.\n const fcpEntryManager = initUnique(opts, FCPEntryManager);\n const visibilityWatcher = getVisibilityWatcher();\n let metric = initMetric('FCP');\n let report;\n const handleEntries = (entries) => {\n for (const entry of entries) {\n if (entry.name === 'first-contentful-paint') {\n po.disconnect();\n // Only report if the page wasn't hidden prior to FCP.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The activationStart reference is used because FCP should be\n // relative to page activation rather than navigation start if the\n // page was prerendered. But in cases where `activationStart` occurs\n // after the FCP, this time should be clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries.push(entry);\n metric.navigationId = entry.navigationId || metric.navigationId;\n // FCP should only be reported once so can report right away\n report(true);\n }\n }\n }\n };\n const po = observe(['paint'], handleEntries);\n if (po) {\n report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n // Only report after a bfcache restore if the `PerformanceObserver`\n // successfully registered or the `paint` entry exists.\n onBFCacheRestore((event) => {\n metric = initMetric('FCP', -1, 'back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());\n report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n doubleRAF(() => {\n metric.value = performance.now() - event.timeStamp;\n report(true);\n });\n });\n }\n if (softNavsEnabled) {\n // As first-contentful-paint is only reported once, we can handle soft\n // navigations afterwards on their own for simplicity, as no need to\n // observe both and sort the entries like for the other metrics\n const handleSoftNavEntries = (entries) => {\n entries.forEach((entry) => {\n // Store the soft navigation entries in the entry manager so that\n // they can be retrieved for attribution if necessary. This code\n // is only used when attribution is enabled which sets the\n // _softNavigationEntryMap.\n if (fcpEntryManager._softNavigationEntryMap && entry.navigationId) {\n storeSoftNavEntry(fcpEntryManager._softNavigationEntryMap, entry);\n }\n // Clamp FCP at 0. It should never be less, but better safe than sorry.\n const FCPTime = Math.max((entry.presentationTime || entry.paintTime || 0) - entry.startTime, 0);\n metric = initMetric('FCP', FCPTime, 'soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);\n report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n report(true);\n });\n };\n observe(['soft-navigation'], handleSoftNavEntries, opts);\n }\n });\n};\n//# sourceMappingURL=onFCP.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { doubleRAF } from './lib/doubleRAF.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { initUnique } from './lib/initUnique.js';\nimport { LayoutShiftManager } from './lib/LayoutShiftManager.js';\nimport { observe } from './lib/observe.js';\nimport { checkSoftNavsEnabled } from './lib/softNavs.js';\nimport { runOnce } from './lib/runOnce.js';\nimport { onFCP } from './onFCP.js';\n/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */\nexport const CLSThresholds = [0.1, 0.25];\n/**\n * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and\n * calls the `callback` function once the value is ready to be reported, along\n * with all `layout-shift` performance entries that were used in the metric\n * value calculation. The reported value is a `double` (corresponding to a\n * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** CLS should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onCLS = (onReport, opts = {}) => {\n const visibilityWatcher = getVisibilityWatcher();\n // Start monitoring FCP so we can only report CLS if FCP is also reported.\n // Note: this is done to match the current behavior of CrUX.\n onFCP(runOnce(() => {\n let metric = initMetric('CLS', 0);\n let report;\n const layoutShiftManager = initUnique(opts, LayoutShiftManager);\n const initNewCLSMetric = (navigationType, navigationId, navigationInteractionId, navigationURL, navigationStartTime) => {\n metric = initMetric('CLS', 0, navigationType, navigationId, navigationInteractionId, navigationURL, navigationStartTime);\n layoutShiftManager._sessionValue = 0;\n report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);\n };\n const updateAndReportMetric = (forceReport = false) => {\n // If the current session value is larger than the current CLS value,\n // update CLS and the entries contributing to it.\n if (layoutShiftManager._sessionValue > metric.value) {\n metric.value = layoutShiftManager._sessionValue;\n metric.entries = layoutShiftManager._sessionEntries;\n }\n report(forceReport);\n };\n const handleSoftNavEntry = (entry) => {\n updateAndReportMetric(true);\n initNewCLSMetric('soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);\n };\n const handleEntries = (entries) => {\n for (const entry of entries) {\n if (entry.entryType === 'soft-navigation') {\n handleSoftNavEntry(entry);\n continue;\n }\n layoutShiftManager._processEntry(entry);\n }\n updateAndReportMetric();\n };\n const types = ['layout-shift'];\n if (checkSoftNavsEnabled(opts)) {\n types.push('soft-navigation');\n }\n const po = observe(types, handleEntries);\n if (po) {\n report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);\n visibilityWatcher.onHidden(() => {\n handleEntries(po.takeRecords());\n report(true);\n });\n // Only report after a bfcache restore if the `PerformanceObserver`\n // successfully registered.\n onBFCacheRestore(() => {\n initNewCLSMetric('back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());\n doubleRAF(report);\n });\n // Queue a task to report (if nothing else triggers a report first).\n // This allows CLS to be reported as soon as FCP fires when\n // `reportAllChanges` is true.\n setTimeout(report);\n }\n }));\n};\n//# sourceMappingURL=onCLS.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { observe } from '../observe.js';\nlet interactionCountEstimate = 0;\nlet minKnownInteractionId = Infinity;\nlet maxKnownInteractionId = 0;\nconst updateEstimate = (entries) => {\n for (const entry of entries) {\n if (entry.interactionId) {\n minKnownInteractionId = Math.min(minKnownInteractionId, entry.interactionId);\n maxKnownInteractionId = Math.max(maxKnownInteractionId, entry.interactionId);\n interactionCountEstimate = maxKnownInteractionId\n ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1\n : 0;\n }\n }\n};\nlet po;\n/**\n * Returns the `interactionCount` value using the native API (if available)\n * or the polyfill estimate in this module.\n */\nexport const getInteractionCount = () => {\n return po ? interactionCountEstimate : (performance.interactionCount ?? 0);\n};\n/**\n * Feature detects native support or initializes the polyfill if needed.\n */\nexport const initInteractionCountPolyfill = () => {\n if ('interactionCount' in performance || po)\n return;\n po = observe(['event'], updateEstimate, {\n durationThreshold: 0,\n });\n};\n//# sourceMappingURL=interactionCountPolyfill.js.map","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getInteractionCount } from './polyfills/interactionCountPolyfill.js';\n// To prevent unnecessary memory usage on pages with lots of interactions,\n// store at most 10 of the longest interactions to consider as INP candidates.\nconst MAX_INTERACTIONS_TO_CONSIDER = 10;\nexport class InteractionManager {\n /**\n * The interaction count at the start of the current navigation, so p98\n * interaction latencies only consider interactions since then.\n *\n * This is per-instance rather than module state: `initUnique()` gives every\n * `onINP()` call its own manager, and a shared counter would let whichever\n * instance resets first hide the interactions from all the others.\n */\n _prevInteractionCount = 0;\n /**\n * A list of longest interactions on the page (by latency) sorted so the\n * longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER\n * long.\n */\n _longestInteractionList = [];\n /**\n * A mapping of longest interactions by their interaction ID.\n * This is used for faster lookup.\n */\n _longestInteractionMap = new Map();\n _onBeforeProcessingEntry;\n _onAfterProcessingINPCandidate;\n /**\n * Returns the interaction count since the start of the current navigation\n * (or the full page lifecycle if there were no soft navs / bfcache restores).\n */\n _getInteractionCountForNavigation() {\n return getInteractionCount() - this._prevInteractionCount;\n }\n _resetInteractions() {\n this._prevInteractionCount = getInteractionCount();\n this._longestInteractionList.length = 0;\n this._longestInteractionMap.clear();\n }\n /**\n * Returns the estimated p98 longest interaction based on the stored\n * interaction candidates and the interaction count for the current page.\n */\n _estimateP98LongestInteraction(navigationType) {\n const interactionCountForNavigation = this._getInteractionCountForNavigation();\n const candidateInteractionIndex = Math.min(this._longestInteractionList.length - 1, Math.floor(interactionCountForNavigation / 50));\n // If we have a non-zero interactionCountForNavigation but no\n // candidateInteractionIndex, then it's below the 16ms limit\n // so report a dummy 8ms interaction. This is only needed for\n // soft-navs and bfcache restores as `first-input` handles the\n // rest.\n if (interactionCountForNavigation &&\n candidateInteractionIndex === -1 &&\n (navigationType === 'soft-navigation' ||\n navigationType === 'back-forward-cache')) {\n return {\n _latency: 8,\n id: -1,\n entries: [],\n };\n }\n return this._longestInteractionList[candidateInteractionIndex];\n }\n /**\n * Takes a performance entry and adds it to the list of worst interactions\n * if its duration is long enough to make it among the worst. If the\n * entry is part of an existing interaction, it is merged and the latency\n * and entries list is updated as needed.\n */\n _processEntry(entry) {\n this._onBeforeProcessingEntry?.(entry);\n // Skip further processing for entries that cannot be INP candidates.\n if (!entry.interactionId)\n return;\n // The least-long of the 10 longest interactions.\n const minLongestInteraction = this._longestInteractionList.at(-1);\n let interaction = this._longestInteractionMap.get(entry.interactionId);\n // Only process the entry if it's possibly one of the ten longest,\n // or if it's part of an existing interaction.\n if (interaction ||\n this._longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||\n // If the above conditions are false, `minLongestInteraction` will be set.\n entry.duration > minLongestInteraction._latency) {\n // If the interaction already exists, update it. Otherwise create one.\n if (interaction) {\n // If the new entry has a longer duration, replace the old entries,\n // otherwise add to the array.\n if (entry.duration > interaction._latency) {\n interaction.entries = [entry];\n interaction._latency = entry.duration;\n }\n else if (entry.duration === interaction._latency &&\n entry.startTime === interaction.entries[0].startTime) {\n interaction.entries.push(entry);\n }\n }\n else {\n interaction = {\n id: entry.interactionId,\n entries: [entry],\n _latency: entry.duration,\n };\n this._longestInteractionMap.set(interaction.id, interaction);\n this._longestInteractionList.push(interaction);\n }\n // Sort the entries by latency (descending) and keep only the top ten.\n this._longestInteractionList.sort((a, b) => b._latency - a._latency);\n if (this._longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {\n const removedInteractions = this._longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER);\n for (const interaction of removedInteractions) {\n this._longestInteractionMap.delete(interaction.id);\n }\n }\n // Call any post-processing on the interaction\n this._onAfterProcessingINPCandidate?.(interaction);\n }\n }\n}\n//# sourceMappingURL=InteractionManager.js.map","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { runOnce } from './runOnce.js';\n/**\n * Runs the passed callback during the next idle period, or immediately\n * if the browser's visibility state is (or becomes) hidden.\n */\nexport const whenIdleOrHidden = (cb) => {\n // Cap the requestIdleCallback to 1 sec for very busy apps\n // https://github.com/GoogleChrome/web-vitals/issues/754\n // If not using rIC, then the setTimeout timeout should be 0\n const timeout = 'requestIdleCallback' in globalThis ? 1000 : 0;\n const rIC = globalThis.requestIdleCallback || setTimeout;\n const cIC = globalThis.cancelIdleCallback || clearTimeout;\n // If the document is hidden, run the callback immediately, otherwise\n // race an idle callback with the next `visibilitychange` event.\n if (document.visibilityState === 'hidden') {\n cb();\n }\n else {\n const wrappedCb = runOnce(cb);\n let idleHandle = -1;\n const onHidden = () => {\n cIC(idleHandle);\n wrappedCb();\n };\n addEventListener('visibilitychange', onHidden, { once: true, capture: true });\n idleHandle = rIC(() => {\n removeEventListener('visibilitychange', onHidden, { capture: true });\n wrappedCb();\n }, { timeout: timeout });\n }\n};\n//# sourceMappingURL=whenIdleOrHidden.js.map","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { initUnique } from './lib/initUnique.js';\nimport { InteractionManager } from './lib/InteractionManager.js';\nimport { observe } from './lib/observe.js';\nimport { checkSoftNavsEnabled } from './lib/softNavs.js';\nimport { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill.js';\nimport { whenActivated } from './lib/whenActivated.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden.js';\n/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */\nexport const INPThresholds = [200, 500];\n// The default `durationThreshold` used across this library for observing\n// `event` entries via PerformanceObserver.\n// Event Timing entries have their durations rounded to the nearest 8ms,\n// so a duration of 40ms would be any event that spans 2.5 or more frames\n// at 60Hz. This threshold is chosen to strike a balance between usefulness\n// and performance. Running this callback for any interaction that spans\n// just one or two frames is likely not worth the insight that could be\n// gained.\nconst DEFAULT_DURATION_THRESHOLD = 40;\n/**\n * Calculates the [INP](https://web.dev/articles/inp) value for the current\n * page and calls the `callback` function once the value is ready, along with\n * the `event` performance entries reported for that interaction. The reported\n * value is a `DOMHighResTimeStamp`.\n *\n * A custom `durationThreshold` configuration option can optionally be passed\n * to control what `event-timing` entries are considered for INP reporting. The\n * default threshold is `40`, which means INP scores of less than 40 will not\n * be reported. To avoid reporting no interactions in these cases, the library\n * will fall back to the input delay of the first interaction. Note that this\n * will not affect your 75th percentile INP value unless that value is also\n * less than 40 (well below the recommended\n * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** INP should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onINP = (onReport, opts = {}) => {\n // Return if the browser doesn't support all APIs needed to measure INP.\n if (!(globalThis.PerformanceEventTiming &&\n 'interactionId' in PerformanceEventTiming.prototype)) {\n return;\n }\n const visibilityWatcher = getVisibilityWatcher();\n whenActivated(() => {\n // TODO(philipwalton): remove once the polyfill is no longer needed.\n initInteractionCountPolyfill();\n let metric = initMetric('INP');\n let report;\n const interactionManager = initUnique(opts, InteractionManager);\n const initNewINPMetric = (navigationType, navigationId, navigationInteractionId, navigationURL, navigationStartTime) => {\n interactionManager._resetInteractions();\n metric = initMetric('INP', -1, navigationType, navigationId, navigationInteractionId, navigationURL, navigationStartTime);\n report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n };\n const updateINPMetric = () => {\n const inp = interactionManager._estimateP98LongestInteraction(metric.navigationType);\n if (inp && inp._latency !== metric.value) {\n metric.value = inp._latency;\n metric.entries = inp.entries;\n report();\n }\n };\n const handleSoftNavEntry = (entry) => {\n updateINPMetric();\n report(true);\n initNewINPMetric('soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);\n };\n const handleEntries = (entries, forceReport = false) => {\n // Queue the `handleEntries()` callback in the next idle task.\n // This is needed to increase the chances that all event entries that\n // occurred between the user interaction and the next paint\n // have been dispatched. Note: there is currently an experiment\n // running in Chrome (EventTimingKeypressAndCompositionInteractionId)\n // 123+ that if rolled out fully may make this no longer necessary.\n whenIdleOrHidden(() => {\n for (const entry of entries) {\n if (entry.entryType === 'soft-navigation') {\n handleSoftNavEntry(entry);\n continue;\n }\n interactionManager._processEntry(entry);\n }\n updateINPMetric();\n if (forceReport) {\n report(true);\n }\n });\n };\n const types = ['event', 'first-input'];\n if (checkSoftNavsEnabled(opts)) {\n types.push('soft-navigation');\n }\n const po = observe(types, handleEntries, {\n ...opts,\n durationThreshold: opts.durationThreshold ?? DEFAULT_DURATION_THRESHOLD,\n });\n report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n if (po) {\n visibilityWatcher.onHidden(() => {\n handleEntries(po.takeRecords(), true);\n });\n // Only report after a bfcache restore if the `PerformanceObserver`\n // successfully registered.\n onBFCacheRestore(() => {\n initNewINPMetric('back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());\n });\n }\n });\n};\n//# sourceMappingURL=onINP.js.map","/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport class LCPEntryManager {\n _onBeforeProcessingEntry;\n _softNavigationEntryMap;\n _processEntry(entry) {\n this._onBeforeProcessingEntry?.(entry);\n }\n}\n//# sourceMappingURL=LCPEntryManager.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { LCPEntryManager } from './lib/LCPEntryManager.js';\nimport { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { doubleRAF } from './lib/doubleRAF.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { checkSoftNavsEnabled, storeSoftNavEntry } from './lib/softNavs.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { initUnique } from './lib/initUnique.js';\nimport { observe } from './lib/observe.js';\nimport { whenActivated } from './lib/whenActivated.js';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden.js';\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds = [2500, 4000];\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport, opts = {}) => {\n // As InteractionContentfulPaint entries used by soft navs can emit after\n // LCP is finalized, we need a flag to know to ignore them.\n let isFinalized = false;\n const softNavsEnabled = checkSoftNavsEnabled(opts);\n whenActivated(() => {\n let visibilityWatcher = getVisibilityWatcher();\n let metric = initMetric('LCP');\n let report;\n const lcpEntryManager = initUnique(opts, LCPEntryManager);\n const initNewLCPMetric = (navigation, navigationId, navigationInteractionId, navigationURL, navigationStartTime) => {\n metric = initMetric('LCP', -1, navigation, navigationId, navigationInteractionId, navigationURL, navigationStartTime);\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n // Reset the finalized flag\n isFinalized = false;\n // If it's a soft nav, then need to reset the visibilityWatcher\n if (navigation === 'soft-navigation') {\n visibilityWatcher = getVisibilityWatcher(true);\n }\n };\n const handleSoftNavEntry = (entry) => {\n if (lcpEntryManager._softNavigationEntryMap && entry.navigationId) {\n storeSoftNavEntry(lcpEntryManager._softNavigationEntryMap, entry);\n }\n if (!isFinalized)\n report(true);\n initNewLCPMetric('soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);\n // Soft Navs should contain the largest paint until now, so handle that\n // as if it just happened, then listen for more.\n // It can however be null in rare circumstances\n // (see https://github.com/GoogleChrome/web-vitals/issues/725)\n const largestInteractionContentfulPaint = entry.getLargestInteractionContentfulPaint?.();\n if (largestInteractionContentfulPaint) {\n handleEntries([largestInteractionContentfulPaint]);\n }\n };\n const handleEntries = (entries) => {\n // If reportAllChanges is set or soft navs is enabled then call this\n // function for each entry, otherwise only consider the last one.\n if (!opts.reportAllChanges && !softNavsEnabled) {\n entries = entries.slice(-1);\n }\n for (const entry of entries) {\n if (!entry)\n continue;\n if (entry.entryType === 'soft-navigation') {\n handleSoftNavEntry(entry);\n continue;\n }\n let value = 0;\n let metricEntries = [];\n let renderTime = entry.startTime;\n if (entry.entryType === 'largest-contentful-paint') {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n value = Math.max(entry.startTime - getActivationStart(), 0);\n lcpEntryManager._processEntry(entry);\n metricEntries = [entry];\n }\n else if (entry.entryType === 'interaction-contentful-paint') {\n const ICPEntry = entry;\n // InteractionContentfulPaints should only happen after a\n // PerformanceSoftNavigation so the metric should have been set\n // with a non-zero navigationId mapping to a soft nav.\n if (!metric.navigationId)\n continue;\n // Ignore interactions not for this soft nav\n // (either paints that have bled into this interaction or paints when\n // we should have already finalized)\n if ('interactionId' in ICPEntry &&\n ICPEntry.interactionId != metric.navigationInteractionId) {\n continue;\n }\n renderTime = ICPEntry.largestContentfulPaint?.renderTime || 0;\n // Paints should never be less than 0 but add cap just in case\n value = Math.max(renderTime - entry.startTime, 0);\n if (ICPEntry.largestContentfulPaint) {\n lcpEntryManager._processEntry(ICPEntry.largestContentfulPaint);\n metricEntries = [ICPEntry.largestContentfulPaint];\n }\n }\n // Only report if the page wasn't hidden prior to LCP.\n if (renderTime < visibilityWatcher.firstHiddenTime) {\n metric.value = value;\n metric.entries = metricEntries;\n report();\n }\n }\n };\n const types = ['largest-contentful-paint'];\n if (softNavsEnabled) {\n types.push('interaction-contentful-paint', 'soft-navigation');\n }\n const po = observe(types, handleEntries);\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n const finalizeEventTypes = ['keydown', 'click', 'visibilitychange'];\n const finalizeLCP = (event) => {\n if (event.isTrusted && !isFinalized) {\n // Wrap the listener in an idle callback so it's run in a separate\n // task to reduce potential INP impact.\n // https://github.com/GoogleChrome/web-vitals/issues/383\n const metricIdToFinalize = metric.id;\n whenIdleOrHidden(() => {\n if (!isFinalized) {\n if (!softNavsEnabled) {\n // Do some clean up since these won't be needed anymore.\n po.disconnect();\n for (const type of finalizeEventTypes) {\n removeEventListener(type, finalizeLCP, { capture: true });\n }\n }\n // As this is in a whenIdleOrHidden check, whether we're still\n // on the metric you meant to finalize, and ignore if we've moved\n // on in the meantime.\n if (metricIdToFinalize === metric.id) {\n isFinalized = true;\n report(true);\n }\n }\n });\n }\n };\n // Finalize the current LCP after input or visibilitychange.\n // Although the browser will automatically stop emitting entries in these\n // cases, we don't know it's finalized, so we track to allow early report.\n // Note: while scrolling is an input that stops LCP observation, it's\n // unreliable since it can be programmatically generated.\n // See: https://github.com/GoogleChrome/web-vitals/issues/75\n for (const type of finalizeEventTypes) {\n addEventListener(type, finalizeLCP, {\n capture: true,\n });\n }\n // Only report after a bfcache restore if the `PerformanceObserver`\n // successfully registered.\n onBFCacheRestore((event) => {\n initNewLCPMetric('back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n doubleRAF(() => {\n metric.value = performance.now() - event.timeStamp;\n isFinalized = true;\n report(true);\n });\n });\n }\n });\n};\n//# sourceMappingURL=onLCP.js.map","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { bindReporter } from './lib/bindReporter.js';\nimport { checkSoftNavsEnabled } from './lib/softNavs.js';\nimport { getNavigationEntry } from './lib/getNavigationEntry.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { getBFCacheRestoreTime, onBFCacheRestore } from './lib/bfcache.js';\nimport { whenActivated } from './lib/whenActivated.js';\n/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */\nexport const TTFBThresholds = [800, 1800];\n/**\n * Runs in the next task after the page is done loading and/or prerendering.\n * @param callback\n */\nconst whenReady = (callback) => {\n if (document.prerendering) {\n whenActivated(() => whenReady(callback));\n }\n else if (document.readyState !== 'complete') {\n addEventListener('load', () => whenReady(callback), true);\n }\n else {\n // Queue a task so the callback runs after `loadEventEnd`.\n setTimeout(callback);\n }\n};\n/**\n * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the\n * current page and calls the `callback` function once the page has loaded,\n * along with the relevant `navigation` performance entry used to determine the\n * value. The reported value is a `DOMHighResTimeStamp`.\n *\n * Note, this function waits until after the page is loaded to call `callback`\n * in order to ensure all properties of the `navigation` entry are populated.\n * This is useful if you want to report on other metrics exposed by the\n * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For\n * example, the TTFB metric starts from the page's [time\n * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it\n * includes time spent on DNS lookup, connection negotiation, network latency,\n * and server processing time.\n */\nexport const onTTFB = (onReport, opts = {}) => {\n const softNavsEnabled = checkSoftNavsEnabled(opts);\n let metric = initMetric('TTFB');\n let report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n whenReady(() => {\n const hardNavEntry = getNavigationEntry();\n if (hardNavEntry) {\n const responseStart = hardNavEntry.responseStart;\n // The activationStart reference is used because TTFB should be\n // relative to page activation rather than navigation start if the\n // page was prerendered. But in cases where `activationStart` occurs\n // after the first byte is received, this time should be clamped at 0.\n metric.value = Math.max(responseStart - getActivationStart(), 0);\n metric.entries = [hardNavEntry];\n report(true);\n // Only report TTFB after bfcache restores if a `navigation` entry\n // was reported for the initial load.\n onBFCacheRestore(() => {\n metric = initMetric('TTFB', 0, 'back-forward-cache', metric.navigationId, metric.navigationInteractionId, metric.navigationURL, getBFCacheRestoreTime());\n report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n report(true);\n });\n // Listen for soft-navigation entries and emit a dummy 0 TTFB entry\n if (softNavsEnabled) {\n const reportSoftNavTTFBs = (entries) => {\n entries.forEach((entry) => {\n if (entry.navigationId) {\n metric = initMetric('TTFB', 0, 'soft-navigation', entry.navigationId, entry.interactionId, entry.name, entry.startTime);\n metric.entries = [entry];\n report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n report(true);\n }\n });\n };\n observe(['soft-navigation'], reportSoftNavTTFBs, opts);\n }\n }\n });\n};\n//# sourceMappingURL=onTTFB.js.map"],"names":["bfcacheRestoreTime","getBFCacheRestoreTime","onBFCacheRestore","cb","addEventListener","event","persisted","timeStamp","bindReporter","callback","metric","thresholds","reportAllChanges","prevValue","delta","forceReport","value","undefined","rating","getRating","doubleRAF","requestAnimationFrame","getNavigationEntry","navigationEntry","performance","getEntriesByType","responseStart","now","getActivationStart","activationStart","firstHiddenTime","onHiddenFunctions","Set","initHiddenTime","document","visibilityState","prerendering","Infinity","onVisibilityUpdate","type","onHiddenFunction","isFinite","removeEventListener","getVisibilityWatcher","reset","firstVisibilityStateHiddenTime","globalThis","find","e","name","startTime","setTimeout","onHidden","add","initMetric","navigationType","navigationId","navigationInteractionId","navigationURL","navigationStartTime","hardNavEntry","hardNavId","_navigationType","wasDiscarded","replace","entries","id","Date","Math","floor","random","instanceMap","WeakMap","initUnique","identityObj","ClassObj","classInstances","get","set","LayoutShiftManager","_onAfterProcessingUnexpectedShift","_sessionValue","_sessionEntries","_processEntry","entry","hadRecentInput","firstSessionEntry","this","lastSessionEntry","at","push","observe","types","opts","supportedTypes","filter","t","PerformanceObserver","supportedEntryTypes","includes","length","po","list","queueMicrotask","getEntries","sort","a","b","duration","buffered","checkSoftNavsEnabled","PerformanceSoftNavigation","prototype","getLargestInteractionContentfulPaint","reportSoftNavs","storeSoftNavEntry","map","size","firstKey","keys","next","delete","runOnce","called","FCPEntryManager","_softNavigationEntryMap","whenActivated","FCPThresholds","onFCP","onReport","softNavsEnabled","fcpEntryManager","visibilityWatcher","report","disconnect","max","forEach","FCPTime","presentationTime","paintTime","interactionId","CLSThresholds","interactionCountEstimate","minKnownInteractionId","maxKnownInteractionId","updateEstimate","min","getInteractionCount","interactionCount","initInteractionCountPolyfill","durationThreshold","InteractionManager","_prevInteractionCount","_longestInteractionList","_longestInteractionMap","Map","_onBeforeProcessingEntry","_onAfterProcessingINPCandidate","_getInteractionCountForNavigation","_resetInteractions","clear","_estimateP98LongestInteraction","interactionCountForNavigation","candidateInteractionIndex","_latency","minLongestInteraction","interaction","removedInteractions","splice","whenIdleOrHidden","timeout","rIC","requestIdleCallback","cIC","cancelIdleCallback","clearTimeout","wrappedCb","idleHandle","once","capture","INPThresholds","LCPEntryManager","LCPThresholds","TTFBThresholds","whenReady","readyState","onCLS","layoutShiftManager","initNewCLSMetric","updateAndReportMetric","handleSoftNavEntry","handleEntries","entryType","takeRecords","onINP","PerformanceEventTiming","interactionManager","initNewINPMetric","updateINPMetric","inp","onLCP","isFinalized","lcpEntryManager","initNewLCPMetric","navigation","largestInteractionContentfulPaint","slice","metricEntries","renderTime","ICPEntry","largestContentfulPaint","finalizeEventTypes","finalizeLCP","isTrusted","metricIdToFinalize","onTTFB"],"mappings":"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"}