this repo has no description
at main 85 lines 2.9 kB view raw
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