this repo has no description
1import { bindReporter } from './lib/bindReporter.js';
2import { getActivationStart } from './lib/getActivationStart.js';
3import { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';
4import { initMetric } from './lib/initMetric.js';
5import { observe } from './lib/observe.js';
6import { onHidden } from './lib/onHidden.js';
7
8/*
9 * Copyright 2020 Google LLC
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * https://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24const reportedMetricIDs = {};
25
26/**
27 * Calculates the [LCP](https://web.dev/lcp/) value for the current page and
28 * calls the `callback` function once the value is ready (along with the
29 * relevant `largest-contentful-paint` performance entry used to determine the
30 * value). The reported value is a `DOMHighResTimeStamp`.
31 */
32const onLCP = (onReport) => {
33 const visibilityWatcher = getVisibilityWatcher();
34 const metric = initMetric('LCP');
35 let report;
36
37 const handleEntries = (entries) => {
38 const lastEntry = entries[entries.length - 1] ;
39 if (lastEntry) {
40 // The startTime attribute returns the value of the renderTime if it is
41 // not 0, and the value of the loadTime otherwise. The activationStart
42 // reference is used because LCP should be relative to page activation
43 // rather than navigation start if the page was prerendered.
44 const value = Math.max(lastEntry.startTime - getActivationStart(), 0);
45
46 // Only report if the page wasn't hidden prior to LCP.
47 if (value < visibilityWatcher.firstHiddenTime) {
48 metric.value = value;
49 metric.entries = [lastEntry];
50 report();
51 }
52 }
53 };
54
55 const po = observe('largest-contentful-paint', handleEntries);
56
57 if (po) {
58 report = bindReporter(onReport, metric);
59
60 const stopListening = () => {
61 if (!reportedMetricIDs[metric.id]) {
62 handleEntries(po.takeRecords() );
63 po.disconnect();
64 reportedMetricIDs[metric.id] = true;
65 report(true);
66 }
67 };
68
69 // Stop listening after input. Note: while scrolling is an input that
70 // stop LCP observation, it's unreliable since it can be programmatically
71 // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75
72 ['keydown', 'click'].forEach(type => {
73 addEventListener(type, stopListening, { once: true, capture: true });
74 });
75
76 onHidden(stopListening, true);
77
78 return stopListening;
79 }
80
81 return;
82};
83
84export { onLCP };
85//# sourceMappingURL=getLCP.js.map