Skip to content
Now accepting Q2 projects — limited slots available. Get started →
SEO · Updated Apr 30, 2026

What is Interaction to Next Paint (INP)?

Interaction to Next Paint (INP) is a Core Web Vital that measures a page's overall responsiveness to user interactions.

What is Interaction to Next Paint (INP)?

Interaction to Next Paint (INP) is the Core Web Vital that measures how fast your page actually responds when someone clicks, taps, or presses a key. Unlike First Input Delay (FID)—which only looked at the first interaction—INP tracks responsiveness across the entire session and reports the worst interaction at the 75th percentile. Google replaced FID with INP in March 2024. Good is 200ms or less. 200–500ms needs work. Above 500ms is poor. This directly affects search rankings—it's one of three metrics (with LCP and CLS) in Google's page experience signals. Classic pain point: e-commerce product page where clicking "Add to Cart" takes 400ms to show any visual feedback. INP will flag that.

How it works

INP measures the gap from when a user starts an interaction to when the browser paints the next frame showing that something happened. Every interaction has three phases:

  1. Input delay — event sits in the queue waiting for the main thread.
  2. Processing time — your JavaScript actually runs.
  3. Presentation delay — browser recalcs styles, layout, composites, paints.

INP = input delay + processing time + presentation delay, for the worst (or near-worst) interaction you see during the session.

The browser's PerformanceObserver API with event entries exposes per-interaction timing. Google's web-vitals library (v4+) makes this dead simple:

import { onINP } from 'web-vitals';

onINP((metric) => {
  console.log('INP:', metric.value, 'ms');
  console.log('Worst interaction:', metric.entries[0]);
});

The metric only finalizes when the user leaves (on visibilitychange) because any later interaction could become the new worst. Chrome reports INP in CrUX (Chrome User Experience Report), which is what Google Search actually uses. Lighthouse (v12+) can simulate INP in "Timespan" mode, but field data from CrUX or RUM is what counts.

Here's the thing: a click handler that blocks the main thread for 300ms creates 300ms of processing time. But even a fast handler preceded by a 250ms main-thread task (say, some third-party script parsing) creates 250ms of input delay. Both paths wreck your INP.

When to use it

INP should be monitored on every page where you care about ranking or UX. It's not optional—it's a ranking signal.

Prioritize INP optimization when you've got:

  • Heavy interactive elements (filters, modals, carousels, form submissions)
  • SPAs where client-side route transitions trigger expensive re-renders
  • Significant third-party JavaScript (chat widgets, analytics, ad scripts)
  • E-commerce checkout flows where slow feedback kills conversion

INP matters less on:

  • Purely static content (blog posts, docs)
  • Pages where users mostly scroll without clicking
  • Server-rendered pages with minimal client-side JS

On our projects, the biggest INP wins consistently come from three places: breaking up long tasks with scheduler.yield(), deferring non-critical third-party scripts, and moving expensive state updates off the main thread with web workers.

INP vs alternatives

Metric What it measures Scope Status
INP Full interaction latency (input delay + processing + paint) All interactions, worst reported Active Core Web Vital (March 2024)
FID Input delay only of the first interaction Single interaction Deprecated as CWV (March 2024)
TBT (Total Blocking Time) Sum of blocking portions of long tasks during load Lab-only, load phase Lighthouse proxy for INP
TTI (Time to Interactive) When main thread is consistently idle Lab-only, load phase Largely deprecated

FID was easier to pass—most sites scored well because it only measured delay, not processing or paint, and only for the first tap. INP is a harder bar. When Google flipped the switch in March 2024, roughly 30% of origins that passed FID failed INP according to CrUX. TBT in Lighthouse is still a useful lab proxy (weighted 30% in performance score), but it doesn't capture post-load interactions.

Real-world example

We've shipped INP fixes on 50+ projects. Recent case: Next.js 14 e-commerce site with faceted search filters. Each filter click triggered a full product list re-render—380ms processing time on mid-range Android, pushing INP to ~450ms (poor). We made three changes: (1) wrapped the filter state update with React.startTransition to let the browser paint an immediate visual indicator, (2) used scheduler.yield() between filter logic and DOM update to break the long task, (3) lazy-loaded the third-party reviews widget that was adding 120ms of input delay during initialization. Result: INP dropped to 140ms at the 75th percentile in CrUX within 28 days. Went from "poor" to "good" and we saw measurable ranking improvement for the target keywords.

Frequently asked questions about Interaction to Next Paint (INP)

Is INP the same as First Input Delay (FID)?
No. FID only measured the input delay of the very first interaction on a page—it ignored processing time, paint time, and every subsequent interaction. INP measures the full duration (input delay + processing + presentation delay) across all interactions during a session, then reports the worst one. FID was officially replaced by INP as a Core Web Vital in March 2024. In practice, most sites that passed FID easily could still have terrible INP because FID ignored the expensive click handlers that happen after page load. INP is a much more honest measure of real-world responsiveness.
When did INP become a Core Web Vital?
Google announced INP as an experimental metric in May 2022, promoted it to "pending" Core Web Vital status in May 2023, and officially made it a stable Core Web Vital on March 12, 2024, simultaneously retiring FID. The transition gave developers almost two years of runway. Since March 2024, INP has been the responsiveness component in Google's page experience ranking signals alongside Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS). If you're still tracking FID in your dashboards, it's time to switch.
What's the alternative to measuring INP?
In lab environments, Total Blocking Time (TBT) is the closest proxy for INP. Lighthouse uses TBT as 30% of the performance score, and Google has confirmed it correlates well with INP. However, TBT only measures main-thread blocking during the page load phase—it can't capture interactions that happen minutes into a session. For real responsiveness data, there's no substitute for field measurement via CrUX, or your own RUM setup using the `web-vitals` library. Our preferred stack is the `web-vitals` v4 library sending data to a custom analytics endpoint, which gives us per-interaction breakdowns that CrUX alone can't provide.
How do I fix a bad INP score?
Start by identifying *which* interaction is the culprit—use Chrome DevTrace or the `web-vitals` attribution build to get the specific element and event. Then attack the three phases in order. For input delay: break up long tasks, defer third-party scripts, and avoid running expensive code during idle periods. For processing time: optimize event handlers, use `requestAnimationFrame` or `scheduler.yield()` to yield back to the browser, and consider `React.startTransition` or similar framework primitives. For presentation delay: reduce DOM size, avoid forced reflows in handlers, and minimize the render cost of your updates. On most projects we've worked on, the biggest single win is deferring or lazy-loading third-party scripts that monopolize the main thread.
Get in touch

Let's build
something together.

Whether it's a migration, a new build, or an SEO challenge — the Social Animal team would love to hear from you.

Get in touch →