INP (Interaction to Next Paint) Explained: The Responsiveness Metric
INP replaced FID as a Core Web Vital in 2024. Here is what Interaction to Next Paint measures, what a good score is, what causes poor INP, and how to fix it.
For years, the responsiveness slot in Core Web Vitals was held by First Input Delay — a metric so easy to pass that most sites ignored it. That changed in March 2024, when Google replaced FID with Interaction to Next Paint (INP), a far stricter and more honest measure of how responsive a page really feels. Many sites that sailed through FID now have genuine INP work to do. This guide explains what INP measures, what a good score looks like, what causes poor INP, and how to fix it.
It is the deep dive behind the responsiveness metric in Core Web Vitals explained.
What INP measures
INP measures the delay between a user interaction and the page visibly responding. Each time a user taps, clicks or presses a key, the browser must run any associated JavaScript, perform layout and style work, and then paint a new frame reflecting the result. INP measures the time from the interaction to that next paint, and over the whole visit it reports a value close to the worst interaction (with a small allowance for outliers on pages with many interactions). In plain terms: INP asks "across everything the user did on this page, how laggy was the laggiest meaningful interaction?" That is much closer to how people actually perceive responsiveness than a single first-interaction measurement.
The thresholds
INP is assessed at the 75th percentile of interactions:
| INP | Rating |
|---|---|
| ≤ 200ms | Good |
| 200ms - 500ms | Needs improvement |
| > 500ms | Poor |
The 75th-percentile rule matters: it is not enough for most interactions to be fast if a meaningful share are slow. A page that responds instantly to a click but stutters when opening a menu or filtering a list can still fail, because that stutter is what the user remembers.
Why Google replaced FID with INP
The change was about honesty. First Input Delay measured only the input delay of the first interaction — the time before the browser even began processing it — and ignored everything after. A page could record a great FID while feeling sluggish on every subsequent tap, because FID never looked past the first one and never measured the full round-trip to a visual response. INP fixes both flaws: it looks at all interactions and measures the complete time to the next paint. The result is a metric that reflects the lived experience of using a page, and a higher bar that has pushed responsiveness up the priority list for many teams. If your site passed FID comfortably and you have not checked INP since early 2024, it is worth looking now.
What causes poor INP
INP problems are, overwhelmingly, JavaScript problems on the main thread. The browser handles user input on the same main thread that runs your scripts, so when that thread is busy, input waits. The usual causes:
- Long tasks. Any JavaScript task that runs for 50ms or more blocks the thread; while it runs, taps and clicks queue up unanswered.
- Heavy event handlers. An interaction whose handler does expensive work — large DOM updates, synchronous network or storage calls, costly calculations — is slow to respond by definition.
- Too much JavaScript overall. Large bundles and many third-party scripts keep the main thread perpetually busy, especially during the page's first seconds.
- Forced synchronous layout. Reading and writing layout properties in a way that forces the browser to recalculate mid-interaction adds delay.
- A very large or complex DOM, which makes the paint after an interaction expensive.
How to measure INP
Because INP is a real-user metric, field data is what counts. Check it in PageSpeed Insights (field section), the Core Web Vitals report in Google Search Console, and the Chrome UX Report. For pinpointing the slow interactions, use the Performance panel in Chrome DevTools, which now highlights interactions and their breakdown, and the open-source web-vitals JavaScript library, which can attribute INP to specific interactions and elements from your real users. Lab tools can simulate interactions, but INP is best understood from real behaviour, since which interactions matter depends on how people actually use the page. A broad audit tool such as StackOptic will also report INP within the Core Web Vitals picture.
How to improve INP
The throughline of every INP fix is doing less work on the main thread, and not hogging it:
- Break up long tasks. Split big chunks of JavaScript into smaller pieces and yield to the main thread between them (for example with scheduling APIs or strategic
await), so the browser can answer input in the gaps. - Defer and reduce JavaScript. Load non-critical scripts later, code-split so each page ships only what it needs, and audit third-party tags ruthlessly — they are a frequent INP culprit.
- Keep interaction handlers light. Do the minimum needed to show a visual response immediately, and push heavy follow-up work to after the next paint (or to a web worker).
- Avoid layout thrashing. Batch DOM reads and writes so you do not force repeated synchronous layout during an interaction.
- Simplify the DOM where it is excessively large, to make post-interaction painting cheaper.
Make one change at a time and re-check field data, because INP can be dominated by a single bad interaction that, once fixed, moves the whole metric.
Framework considerations
Modern frameworks can both help and hurt INP. Hydration — the process of making server-rendered HTML interactive — can create a burst of main-thread work that delays early interactions, which is why techniques like partial or progressive hydration, islands architecture and streaming have become popular. Whatever the framework, the principles are the same: ship less JavaScript, hydrate less and later where you can, and keep the work triggered by interactions small. A heavy single-page app is not doomed to poor INP, but it has to be deliberate about main-thread budgets in a way a simple site does not. It also helps to remember that the framework is rarely the villain by itself — it is the accumulation of features, analytics, A/B testing scripts, chat widgets and other additions on top of it that fills the main thread. Auditing what you have actually loaded onto the page is often more productive than blaming the framework, and it is usually where the easy INP wins are hiding.
A worked example: finding the slow interaction
Suppose your INP is reported as 480ms — firmly "needs improvement". Because INP reflects the worst meaningful interaction, the goal is to find which one. Open the Performance panel in Chrome DevTools, record while you reproduce typical interactions — opening the menu, filtering a list, expanding an accordion — and look for the interaction with the longest "input to next paint" duration. Say it is the filter control: when clicked, it runs a long, synchronous task that rebuilds a large part of the DOM before the browser can paint. That single handler is dragging your whole INP down. The fix is targeted: show an immediate visual acknowledgement (a loading state) on click, then perform the heavy rebuild in smaller chunks that yield to the main thread, so input is never blocked for long. Re-measure in the field, and because that one interaction was the bottleneck, the whole metric improves. This is the typical shape of INP work — not a broad, even slowdown, but one or two expensive interactions hiding among many fast ones, which is why diagnosis matters as much as the fix.
INP and the bigger performance picture
INP rarely lives in isolation. The same excess JavaScript that hurts INP often hurts LCP too — by competing for the network and the main thread during load — and contributes to a heavy page overall. That is actually good news: the foundational fixes (shipping less JavaScript, deferring the non-critical, auditing third parties, and respecting a main-thread budget) improve responsiveness and loading at the same time. So rather than treating INP as a standalone target to chase in isolation, fold it into a broader performance discipline. A site that is deliberate about how much code it ships, and when, tends to do well across all of Core Web Vitals, because the root cause of most field failures — too much main-thread work at the wrong moment — is shared. Fix the cause and several metrics improve together, which is a far better return than optimising each one separately.
Common mistakes
- Assuming a pass because FID was fine — INP is stricter and measures more.
- Optimising load speed only and ignoring responsiveness after load.
- Letting third-party scripts run unchecked, then wondering why taps lag.
- Measuring only in the lab, when INP depends on real interaction patterns.
Go deeper
- The full set: Core Web Vitals explained.
- Performance feeds AI visibility too: how to check if your site is ready for AI search.
Want INP and the rest of your Core Web Vitals measured in seconds? Analyse any URL with StackOptic — free, no sign-up.
Frequently asked questions
What is INP (Interaction to Next Paint)?
INP is a Core Web Vital that measures a page's responsiveness to user input. For each interaction — a tap, click or key press — it measures the time from the interaction until the next frame is painted showing a visual response, and reports a value close to the worst interaction across the visit. A low INP means the page reacts promptly every time, which is what users perceive as 'snappy'.
What is a good INP score?
At the 75th percentile of interactions, a good INP is 200 milliseconds or less. Between 200 and 500 milliseconds is 'needs improvement', and above 500 milliseconds is 'poor'. Because it is measured at the 75th percentile across all interactions, you need the page to respond quickly consistently, not just on the first or the average interaction.
How is INP different from FID?
First Input Delay (FID) only measured the input delay of the very first interaction — and only the delay before processing began, not the full time to a visual response. That made it easy to pass and unrepresentative. INP considers all interactions throughout the visit and measures the complete time to the next paint, so it captures real sluggishness FID missed. INP replaced FID as a Core Web Vital in March 2024.
What causes poor INP?
Almost always JavaScript on the main thread. Long tasks (chunks of JS that run for 50ms or more) block the browser from responding to input; heavy or inefficient event handlers delay the response to a specific interaction; large scripts and excessive third-party tags keep the main thread busy. A very large or complex DOM can also make rendering the response slow.
How do I improve INP?
Reduce and restructure main-thread work. Break long tasks into smaller pieces and yield to the main thread so input can be handled between them; defer or remove non-critical and third-party JavaScript; keep event handlers lightweight and move heavy computation off the critical path (for example to a web worker or after the next paint); and simplify large DOMs. Measure with field data, since INP is a real-user metric.
Analyse any website with StackOptic
Get the full technology stack, performance, security and SEO report in seconds — free.
Analyse a websiteRelated articles
How to Test Your Website Speed (Tools and Metrics)
Which tools to use, lab versus field data, and the metrics that matter. Test your site speed with PageSpeed Insights, Lighthouse, WebPageTest and DevTools.
How to Optimize CSS for Faster Pages
CSS is render-blocking, so bloated stylesheets delay your page. How to minify, cut unused CSS, inline critical CSS and defer the rest to speed up FCP and LCP.
What Are Gzip and Brotli Compression (and How to Enable Them)?
Gzip and Brotli shrink HTML, CSS and JavaScript before they are sent. What each is, how Brotli compares to Gzip, how to verify it, and how to enable it.