Suggestions
← TIL
~3 min read
#performance#web-vitals#optimization#chrome#astro

Web Vitals: Measuring INP correctly

INP (Interaction to Next Paint) is the Web Vitals metric that measures the latency of all user interactions throughout their stay on a page. It evaluates the full cycle from the user's interaction until the browser actually paints the next frame on the screen, officially replacing FID.

If your site feels "heavy" when clicking, you probably have an INP issue.

Why is INP the "Final Boss" of Performance?

Unlike LCP (which is loading), INP is pure interactivity. In 2026, with increasingly complex apps, it's not enough for a site to load fast; it must respond fast.

Take a look at the thresholds Google considers acceptable:

< 200ms
Good (Fast)
200 - 500ms
Needs Improvement
> 500ms
Poor (Slow)

Tools: Field vs. Lab

Relying solely on Lighthouse (Lab) is a rookie mistake. INP is a field metric (Real User Monitoring) because it depends on how real users interact with your JavaScript.

As seen in my post about AVIF image optimization, real performance is measured on the user's device, not on your M3 MacBook Pro.

Measurement Strategies

Real Monitoring Advantages (CrUX)

  • Reflects the real user experience
  • Detects issues in specific interactions
  • It's the metric Google uses for ranking

Implementation Challenges

  • Needs real traffic to see CrUX data
  • Hard to replicate locally without throttling tools

Step-by-Step Guide: INP Attribution in Production

To fix INP, you first need to know which element is causing it. It happened to me recently: INP was skyrocketing, and it turned out to be a third-party support chat blocking the Main Thread every time the user tried to scroll.

Configuring INP Attribution

Install the official library

Use `web-vitals` to capture data with attribution support.

Configure the report

Use `onINP` to get the selector of the element that caused the delay.

Send the data

Send `attribution.interactionTarget` to your analytics system (Vercel, GA4, or Mixpanel).

Implementation Example (TypeScript)

src/scripts/performance.ts
TS
import { onINP } from "web-vitals/attribution";

onINP(({ name, value, attribution }) => {
  // Identify exactly what blocked the main thread
  console.log(`INP: ${value}ms`);
  console.log(`Culprit: ${attribution.interactionTarget}`);
  console.log(`Phase: ${attribution.interactionType}`); // click, keydown, etc.

  // Send this to your monitoring API
  sendToAnalytics({
    metric: name,
    value: value,
    target: attribution.interactionTarget,
    delay: attribution.processingDuration,
  });
});

The "Performance Profiler" Trick

If you can't replicate the issue locally, do this: open the Performance Tab in Chrome DevTools, set CPU Throttling to 4x slowdown or 6x slowdown, and interact with the site.

Have you measured your site's INP today? If you don't know where to start, contact me and we'll audit your site's performance together.

Link copied to clipboard