diff --git a/src/attribution/onINP.ts b/src/attribution/onINP.ts index 6cb5c402..09867652 100644 --- a/src/attribution/onINP.ts +++ b/src/attribution/onINP.ts @@ -63,7 +63,7 @@ let pendingLoAFs: PerformanceLongAnimationFrameTiming[] = []; let pendingEntriesGroups: pendingEntriesGroup[] = []; // The `processingEnd` time of most recently-processed event, chronologically. -let latestProcessingEnd: number; +let latestProcessingEnd: number = 0; // A WeakMap to look up the event-timing-entries group of a given entry. // Note that this only maps from "important" entries: either the first input or @@ -188,7 +188,7 @@ const cleanupEntries = () => { // Keep all pending LoAF entries that either: // 1) intersect with entries in the newly cleaned up `pendingEntriesGroups` - // 2) occur after the most recently-processed event entry. + // 2) occur after the most recently-processed event entry (for up to MAX_PREVIOUS_FRAMES) const loafsToKeep: Set = new Set(); for (let i = 0; i < pendingEntriesGroups.length; i++) { const group = pendingEntriesGroups[i]; @@ -198,18 +198,15 @@ const cleanupEntries = () => { }, ); } - for (let i = 0; i < MAX_PREVIOUS_FRAMES; i++) { - // Look at pending LoAF in reverse order so the most recent are first. - const loaf = pendingLoAFs[pendingLoAFs.length - 1 - i]; - - // If we reach LoAFs that overlap with event processing, - // we can assume all previous ones have already been handled. - if (!loaf || loaf.startTime < latestProcessingEnd) break; - - loafsToKeep.add(loaf); - } + const prevFrameIndexCutoff = pendingLoAFs.length - 1 - MAX_PREVIOUS_FRAMES; + // Filter `pendingLoAFs` to preserve LoAF order. + pendingLoAFs = pendingLoAFs.filter((loaf, index) => { + if (loaf.startTime > latestProcessingEnd && index > prevFrameIndexCutoff) { + return true; + } - pendingLoAFs = Array.from(loafsToKeep); + return loafsToKeep.has(loaf); + }); // Reset the idle callback handle so it can be queued again. idleHandle = -1;