@mtdt.temp/browser-rum-core
Version:
Datadog browser RUM core utilities.
68 lines • 3.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.retrieveFirstInputTiming = retrieveFirstInputTiming;
const browser_core_1 = require("@mtdt.temp/browser-core");
/**
* first-input timing entry polyfill based on
* https://github.com/GoogleChrome/web-vitals/blob/master/src/lib/polyfills/firstInputPolyfill.ts
*/
function retrieveFirstInputTiming(configuration, callback) {
const startTimeStamp = (0, browser_core_1.dateNow)();
let timingSent = false;
const { stop: removeEventListeners } = (0, browser_core_1.addEventListeners)(configuration, window, ["click" /* DOM_EVENT.CLICK */, "mousedown" /* DOM_EVENT.MOUSE_DOWN */, "keydown" /* DOM_EVENT.KEY_DOWN */, "touchstart" /* DOM_EVENT.TOUCH_START */, "pointerdown" /* DOM_EVENT.POINTER_DOWN */], (evt) => {
// Only count cancelable events, which should trigger behavior important to the user.
if (!evt.cancelable) {
return;
}
// This timing will be used to compute the "first Input delay", which is the delta between
// when the system received the event (e.g. evt.timeStamp) and when it could run the callback
// (e.g. performance.now()).
const timing = {
entryType: 'first-input',
processingStart: (0, browser_core_1.relativeNow)(),
processingEnd: (0, browser_core_1.relativeNow)(),
startTime: evt.timeStamp,
duration: 0, // arbitrary value to avoid nullable duration and simplify INP logic
name: '',
cancelable: false,
target: null,
toJSON: () => ({}),
};
if (evt.type === "pointerdown" /* DOM_EVENT.POINTER_DOWN */) {
sendTimingIfPointerIsNotCancelled(configuration, timing);
}
else {
sendTiming(timing);
}
}, { passive: true, capture: true });
return { stop: removeEventListeners };
/**
* Pointer events are a special case, because they can trigger main or compositor thread behavior.
* We differentiate these cases based on whether or not we see a pointercancel event, which are
* fired when we scroll. If we're scrolling we don't need to report input delay since FID excludes
* scrolling and pinch/zooming.
*/
function sendTimingIfPointerIsNotCancelled(configuration, timing) {
(0, browser_core_1.addEventListeners)(configuration, window, ["pointerup" /* DOM_EVENT.POINTER_UP */, "pointercancel" /* DOM_EVENT.POINTER_CANCEL */], (event) => {
if (event.type === "pointerup" /* DOM_EVENT.POINTER_UP */) {
sendTiming(timing);
}
}, { once: true });
}
function sendTiming(timing) {
if (!timingSent) {
timingSent = true;
removeEventListeners();
// In some cases the recorded delay is clearly wrong, e.g. it's negative or it's larger than
// the time between now and when the page was loaded.
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/6
// - https://github.com/GoogleChromeLabs/first-input-delay/issues/7
const delay = timing.processingStart - timing.startTime;
if (delay >= 0 && delay < (0, browser_core_1.dateNow)() - startTimeStamp) {
callback(timing);
}
}
}
}
//# sourceMappingURL=firstInputPolyfill.js.map