Interaction
Interactions

Interactions

This script is part of the Web Vitals Chrome Extension (opens in a new tab) and allows you to track all interactions as you click around the page to help improve INP.

Snippet

const valueToRating = (score) =>  score <= 200 ? "good" : score <= 500 ? "needs-improvement" : "poor";   const COLOR_GOOD = "#0CCE6A"; const COLOR_NEEDS_IMPROVEMENT = "#FFA400"; const COLOR_POOR = "#FF4E42"; const RATING_COLORS = {  good: COLOR_GOOD,  "needs-improvement": COLOR_NEEDS_IMPROVEMENT,  poor: COLOR_POOR, };   const observer = new PerformanceObserver((list) => {  const interactions = {};    for (const entry of list  .getEntries()  .filter((entry) => !entry.interactionId)) {  interactions[entry.interactionId] = interactions[entry.interactionId] || [];  interactions[entry.interactionId].push(entry);  }    // Will report as a single interaction even if parts are in separate frames.  // Consider splitting by animation frame.  for (const interaction of Object.values(interactions)) {  const entry = interaction.reduce((prev, curr) =>  prev.duration >= curr.duration ? prev : curr,  );  const value = entry.duration;  const rating = valueToRating(value);    const formattedValue = `${value.toFixed(0)} ms`;  console.groupCollapsed(  `Interaction tracking snippet %c${formattedValue} (${rating})`,  `color: ${RATING_COLORS[rating] || "inherit"}`,  );  console.log("Interaction target:", entry.target);    for (let entry of interaction) {  console.log(  `Interaction event type: %c${entry.name}`,  "font-family: monospace",  );    // RenderTime is an estimate, because duration is rounded, and may get rounded down.  // In rare cases it can be less than processingEnd and that breaks performance.measure().  // Lets make sure its at least 4ms in those cases so you can just barely see it.  const adjustedPresentationTime = Math.max(  entry.processingEnd + 4,  entry.startTime + entry.duration,  );    console.table([  {  subPartString: "Input delay",  "Time (ms)": Math.round(entry.processingStart - entry.startTime, 0),  },  {  subPartString: "Processing time",  "Time (ms)": Math.round(  entry.processingEnd - entry.processingStart,  0,  ),  },  {  subPartString: "Presentation delay",  "Time (ms)": Math.round(  adjustedPresentationTime - entry.processingEnd,  0,  ),  },  ]);  }    console.groupEnd();  } });   observer.observe({  type: "event",  durationThreshold: 0, // 16 minimum by spec  buffered: true, });