getLCP.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. const bindReporter = require('./lib/bindReporter.js');
  3. const getActivationStart = require('./lib/getActivationStart.js');
  4. const getVisibilityWatcher = require('./lib/getVisibilityWatcher.js');
  5. const initMetric = require('./lib/initMetric.js');
  6. const observe = require('./lib/observe.js');
  7. const onHidden = require('./lib/onHidden.js');
  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. const reportedMetricIDs = {};
  24. /**
  25. * Calculates the [LCP](https://web.dev/lcp/) value for the current page and
  26. * calls the `callback` function once the value is ready (along with the
  27. * relevant `largest-contentful-paint` performance entry used to determine the
  28. * value). The reported value is a `DOMHighResTimeStamp`.
  29. */
  30. const onLCP = (onReport) => {
  31. const visibilityWatcher = getVisibilityWatcher.getVisibilityWatcher();
  32. const metric = initMetric.initMetric('LCP');
  33. let report;
  34. const handleEntries = (entries) => {
  35. const lastEntry = entries[entries.length - 1] ;
  36. if (lastEntry) {
  37. // The startTime attribute returns the value of the renderTime if it is
  38. // not 0, and the value of the loadTime otherwise. The activationStart
  39. // reference is used because LCP should be relative to page activation
  40. // rather than navigation start if the page was prerendered.
  41. const value = Math.max(lastEntry.startTime - getActivationStart.getActivationStart(), 0);
  42. // Only report if the page wasn't hidden prior to LCP.
  43. if (value < visibilityWatcher.firstHiddenTime) {
  44. metric.value = value;
  45. metric.entries = [lastEntry];
  46. report();
  47. }
  48. }
  49. };
  50. const po = observe.observe('largest-contentful-paint', handleEntries);
  51. if (po) {
  52. report = bindReporter.bindReporter(onReport, metric);
  53. const stopListening = () => {
  54. if (!reportedMetricIDs[metric.id]) {
  55. handleEntries(po.takeRecords() );
  56. po.disconnect();
  57. reportedMetricIDs[metric.id] = true;
  58. report(true);
  59. }
  60. };
  61. // Stop listening after input. Note: while scrolling is an input that
  62. // stop LCP observation, it's unreliable since it can be programmatically
  63. // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75
  64. ['keydown', 'click'].forEach(type => {
  65. addEventListener(type, stopListening, { once: true, capture: true });
  66. });
  67. onHidden.onHidden(stopListening, true);
  68. return stopListening;
  69. }
  70. return;
  71. };
  72. exports.onLCP = onLCP;
  73. //# sourceMappingURL=getLCP.js.map