{"version":3,"file":"getINP.js","sources":["../../../../src/metrics/web-vitals/getINP.ts"],"sourcesContent":["/*\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 */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { initUnique } from './lib/initUnique';\nimport { InteractionManager } from './lib/InteractionManager';\nimport { observe } from './lib/observe';\nimport { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden';\nimport type { INPMetric, INPReportOpts, MetricRatingThresholds } from './types';\n\n/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */\nexport const INPThresholds: MetricRatingThresholds = [200, 500];\n\n// The default `durationThreshold` used across this library for observing\n// `event` entries via PerformanceObserver.\nconst DEFAULT_DURATION_THRESHOLD = 40;\n\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: (metric: INPMetric) => void, opts: INPReportOpts = {}) => {\n // Return if the browser doesn't support all APIs needed to measure INP.\n if (!(globalThis.PerformanceEventTiming && 'interactionId' in PerformanceEventTiming.prototype)) {\n return;\n }\n\n const visibilityWatcher = getVisibilityWatcher();\n\n whenActivated(() => {\n // TODO(philipwalton): remove once the polyfill is no longer needed.\n initInteractionCountPolyfill();\n\n const metric = initMetric('INP');\n // eslint-disable-next-line prefer-const\n let report: ReturnType;\n\n const interactionManager = initUnique(opts, InteractionManager);\n\n const handleEntries = (entries: INPMetric['entries']) => {\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 interactionManager._processEntry(entry);\n }\n\n const inp = interactionManager._estimateP98LongestInteraction();\n\n if (inp && inp._latency !== metric.value) {\n metric.value = inp._latency;\n metric.entries = inp.entries;\n report();\n }\n });\n };\n\n const po = observe('event', handleEntries, {\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.\n durationThreshold: opts.durationThreshold ?? DEFAULT_DURATION_THRESHOLD,\n });\n\n report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n\n if (po) {\n // Also observe entries of type `first-input`. This is useful in cases\n // where the first interaction is less than the `durationThreshold`.\n po.observe({ type: 'first-input', buffered: true });\n\n visibilityWatcher.onHidden(() => {\n handleEntries(po.takeRecords() as INPMetric['entries']);\n report(true);\n });\n }\n });\n};\n"],"names":["getVisibilityWatcher","whenActivated","initInteractionCountPolyfill","initMetric","initUnique","InteractionManager","whenIdleOrHidden","observe","bindReporter"],"mappings":";;;;;;;;;;;;AA4BO,MAAM,aAAA,GAAwC,CAAC,GAAA,EAAK,GAAG;AAI9D,MAAM,0BAAA,GAA6B,EAAA;AA+B5B,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAuC,IAAA,GAAsB,EAAC,KAAM;AAExF,EAAA,IAAI,EAAE,UAAA,CAAW,sBAAA,IAA0B,eAAA,IAAmB,uBAAuB,SAAA,CAAA,EAAY;AAC/F,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,oBAAoBA,yCAAA,EAAqB;AAE/C,EAAAC,2BAAA,CAAc,MAAM;AAElB,IAAAC,qDAAA,EAA6B;AAE7B,IAAA,MAAM,MAAA,GAASC,sBAAW,KAAK,CAAA;AAE/B,IAAA,IAAI,MAAA;AAEJ,IAAA,MAAM,kBAAA,GAAqBC,qBAAA,CAAW,IAAA,EAAMC,qCAAkB,CAAA;AAE9D,IAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,KAAkC;AAOvD,MAAAC,iCAAA,CAAiB,MAAM;AACrB,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,kBAAA,CAAmB,cAAc,KAAK,CAAA;AAAA,QACxC;AAEA,QAAA,MAAM,GAAA,GAAM,mBAAmB,8BAAA,EAA+B;AAE9D,QAAA,IAAI,GAAA,IAAO,GAAA,CAAI,QAAA,KAAa,MAAA,CAAO,KAAA,EAAO;AACxC,UAAA,MAAA,CAAO,QAAQ,GAAA,CAAI,QAAA;AACnB,UAAA,MAAA,CAAO,UAAU,GAAA,CAAI,OAAA;AACrB,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,MAAM,EAAA,GAAKC,eAAA,CAAQ,OAAA,EAAS,aAAA,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOzC,iBAAA,EAAmB,KAAK,iBAAA,IAAqB;AAAA,KAC9C,CAAA;AAED,IAAA,MAAA,GAASC,yBAAA,CAAa,QAAA,EAAU,MAAA,EAAQ,aAAA,EAAe,KAAK,gBAAgB,CAAA;AAE5E,IAAA,IAAI,EAAA,EAAI;AAGN,MAAA,EAAA,CAAG,QAAQ,EAAE,IAAA,EAAM,aAAA,EAAe,QAAA,EAAU,MAAM,CAAA;AAElD,MAAA,iBAAA,CAAkB,SAAS,MAAM;AAC/B,QAAA,aAAA,CAAc,EAAA,CAAG,aAAqC,CAAA;AACtD,QAAA,MAAA,CAAO,IAAI,CAAA;AAAA,MACb,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAC,CAAA;AACH;;;;;"}