diff options
| author | altaf-creator <dev@altafcreator.com> | 2025-11-09 11:15:19 +0800 |
|---|---|---|
| committer | altaf-creator <dev@altafcreator.com> | 2025-11-09 11:15:19 +0800 |
| commit | 8eff962cab608341a6f2fedc640a0e32d96f26e2 (patch) | |
| tree | 05534d1a720ddc3691d346c69b4972555820a061 /frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts | |
pain
Diffstat (limited to 'frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts')
| -rw-r--r-- | frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts b/frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts new file mode 100644 index 0000000..285f319 --- /dev/null +++ b/frontend-old/node_modules/web-vitals/src/attribution/onLCP.ts @@ -0,0 +1,113 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {getNavigationEntry} from '../lib/getNavigationEntry.js'; +import {getSelector} from '../lib/getSelector.js'; +import {onLCP as unattributedOnLCP} from '../onLCP.js'; +import { + LCPAttribution, + LCPMetric, + LCPMetricWithAttribution, + ReportOpts, +} from '../types.js'; + +const attributeLCP = (metric: LCPMetric): LCPMetricWithAttribution => { + // Use a default object if no other attribution has been set. + let attribution: LCPAttribution = { + timeToFirstByte: 0, + resourceLoadDelay: 0, + resourceLoadDuration: 0, + elementRenderDelay: metric.value, + }; + + if (metric.entries.length) { + const navigationEntry = getNavigationEntry(); + if (navigationEntry) { + const activationStart = navigationEntry.activationStart || 0; + const lcpEntry = metric.entries[metric.entries.length - 1]; + const lcpResourceEntry = + lcpEntry.url && + performance + .getEntriesByType('resource') + .filter((e) => e.name === lcpEntry.url)[0]; + + const ttfb = Math.max(0, navigationEntry.responseStart - activationStart); + + const lcpRequestStart = Math.max( + ttfb, + // Prefer `requestStart` (if TOA is set), otherwise use `startTime`. + lcpResourceEntry + ? (lcpResourceEntry.requestStart || lcpResourceEntry.startTime) - + activationStart + : 0, + ); + const lcpResponseEnd = Math.max( + lcpRequestStart, + lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0, + ); + const lcpRenderTime = Math.max( + lcpResponseEnd, + lcpEntry.startTime - activationStart, + ); + + attribution = { + element: getSelector(lcpEntry.element), + timeToFirstByte: ttfb, + resourceLoadDelay: lcpRequestStart - ttfb, + resourceLoadDuration: lcpResponseEnd - lcpRequestStart, + elementRenderDelay: lcpRenderTime - lcpResponseEnd, + navigationEntry, + lcpEntry, + }; + + // Only attribution the URL and resource entry if they exist. + if (lcpEntry.url) { + attribution.url = lcpEntry.url; + } + if (lcpResourceEntry) { + attribution.lcpResourceEntry = lcpResourceEntry; + } + } + } + + // Use Object.assign to set property to keep tsc happy. + const metricWithAttribution: LCPMetricWithAttribution = Object.assign( + metric, + {attribution}, + ); + return metricWithAttribution; +}; + +/** + * 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 + * relevant `largest-contentful-paint` performance entry used to determine the + * value). The reported value is a `DOMHighResTimeStamp`. + * + * If the `reportAllChanges` configuration option is set to `true`, the + * `callback` function will be called any time a new `largest-contentful-paint` + * performance entry is dispatched, or once the final value of the metric has + * been determined. + */ +export const onLCP = ( + onReport: (metric: LCPMetricWithAttribution) => void, + opts?: ReportOpts, +) => { + unattributedOnLCP((metric: LCPMetric) => { + const metricWithAttribution = attributeLCP(metric); + onReport(metricWithAttribution); + }, opts); +}; |
