Skip to content

Commit

Permalink
Merge branch 'v5' into baseline-widely-available
Browse files Browse the repository at this point in the history
  • Loading branch information
philipwalton authored Sep 27, 2024
2 parents 87d8406 + a8f43a8 commit 7abc440
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 24 deletions.
26 changes: 10 additions & 16 deletions src/attribution/onINP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,16 @@ const getIntersectingLoAFs = (

const attributeINP = (metric: INPMetric): INPMetricWithAttribution => {
const firstEntry = metric.entries[0];
const group = entryToEntriesGroupMap.get(firstEntry)!;
const nextPaintTime = firstEntry.startTime + firstEntry.duration;

const group = entryToEntriesGroupMap.get(firstEntry)!;
const processingStart = firstEntry.processingStart;
const processingEnd = group.processingEnd;
// `processingEnd` can extend beyond the event duration in some cases
// (e.g. sync modals like `alert()`, where duration is when the modal is
// shown, but since it's sync, `processingEnd` is when it's dismissed).
// So for the purposes of INP attribution, `processingEnd` is capped at
// `nextPaintTime`: https://github.com/GoogleChrome/web-vitals/issues/492
const processingEnd = Math.min(group.processingEnd, nextPaintTime);

// Sort the entries in processing time order.
const processedEventEntries = group.entries.sort((a, b) => {
Expand All @@ -258,21 +264,9 @@ const attributeINP = (metric: INPMetric): INPMetricWithAttribution => {
// cases where the element is removed from the DOM before reporting happens).
const firstEntryWithTarget = metric.entries.find((entry) => entry.target);
const interactionTargetElement =
firstEntryWithTarget?.target ||
firstEntryWithTarget?.target ??
interactionTargetMap.get(firstEntry.interactionId);

// Since entry durations are rounded to the nearest 8ms, we need to clamp
// the `nextPaintTime` value to be higher than the `processingEnd` or
// end time of any LoAF entry.
const nextPaintTimeCandidates = [
firstEntry.startTime + firstEntry.duration,
processingEnd,
].concat(
longAnimationFrameEntries.map((loaf) => loaf.startTime + loaf.duration),
);

const nextPaintTime = Math.max.apply(Math, nextPaintTimeCandidates);

const attribution: INPAttribution = {
interactionTarget: getSelector(interactionTargetElement),
interactionTargetElement: interactionTargetElement,
Expand All @@ -283,7 +277,7 @@ const attributeINP = (metric: INPMetric): INPMetricWithAttribution => {
longAnimationFrameEntries: longAnimationFrameEntries,
inputDelay: processingStart - firstEntry.startTime,
processingDuration: processingEnd - processingStart,
presentationDelay: Math.max(nextPaintTime - processingEnd, 0),
presentationDelay: nextPaintTime - processingEnd,
loadState: getLoadState(firstEntry.startTime),
};

Expand Down
16 changes: 8 additions & 8 deletions src/attribution/onLCP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ const attributeLCP = (metric: LCPMetric): LCPMetricWithAttribution => {
activationStart
: 0,
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0,
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
lcpEntry.startTime - activationStart,
const lcpResponseEnd = Math.min(
// Cap at LCP time (videos continue downloading after LCP for example)
metric.value,
Math.max(
lcpRequestStart,
lcpResourceEntry ? lcpResourceEntry.responseEnd - activationStart : 0,
),
);

attribution = {
element: getSelector(lcpEntry.element),
timeToFirstByte: ttfb,
resourceLoadDelay: lcpRequestStart - ttfb,
resourceLoadDuration: lcpResponseEnd - lcpRequestStart,
elementRenderDelay: lcpRenderTime - lcpResponseEnd,
elementRenderDelay: metric.value - lcpResponseEnd,
navigationEntry,
lcpEntry,
};
Expand Down

0 comments on commit 7abc440

Please sign in to comment.