Interaction to Next Paint: A Developer's Guide

By PageSpeedPlus Staff
Reading time: 6 minutes

You likely encounter a common challenge with Interaction to Next Paint. Lighthouse looks acceptable, Total Blocking Time seems under control, yet real users still tap Add to Cart, open a filter, or hit a menu button and nothing appears to happen for a beat. That disconnect is exactly why INP matters, because it measures the lag users feel between an interaction and the next visual update on screen. A frustrated man looking at his smartphone while experiencing a delay with a loading spinner icon.

If you want a broader grounding in Web Vitals before going deep on responsiveness, this Web Vitals guide is a useful companion. For teams working across frontend and product language, PinDrop also keeps handy definitions for web app development that help align terminology across design and engineering.

Table of Contents

What Is Interaction to Next Paint

A user clicks a button. The browser accepts the input. The interface still looks frozen. That moment of uncertainty is what Interaction to Next Paint, or INP, is trying to capture.

Google officially replaced First Input Delay with INP as the standard Core Web Vital for responsiveness on March 12, 2024, and INP observes click, tap, and keyboard interactions across the visit, then reports the longest interaction while ignoring outliers, as described by Portent's explanation of the metric change. That makes it much closer to lived UI responsiveness than older metrics that focused on only a narrow slice of the interaction lifecycle.

What matters here is the endpoint. INP isn't asking when the browser noticed the click. It asks when the page was able to show the next paint that reflects that interaction.

Practical rule: If a user can trigger an action but can't see feedback quickly, your interface feels broken even if the network request is fine.

That's why interaction to next paint has become such a useful engineering metric. It matches the way people judge responsiveness. They don't care whether the event queue started on time. They care whether the screen reacted.

How INP Is Calculated and Scored

A page can feel fine in a Lighthouse run and still have bad INP in production. The reason is simple. INP is shaped by one slow interaction anywhere in the visit, not just by work during initial load.

INP is easier to debug when you split a single interaction into three phases. SpeedCurve lays out those phases in its guide to understanding and improving interaction to next paint.

A diagram illustrating the three phases of Interaction to Next Paint: Input Delay, Processing Time, and Presentation Delay.

The three phases

The coffee-shop analogy only works if you carry it all the way through. A user places an order, the barista makes the drink, then the drink reaches the counter. INP follows the same sequence from input to visible result.

Phase What happens Coffee-shop equivalent Typical failure mode
Input Delay The browser has received the interaction but has not started handling it Waiting for the barista to take your order The main thread is tied up by other work
Processing Time Your event handlers and related JavaScript run The barista is making the drink Heavy JavaScript, expensive state updates, or synchronous framework work
Presentation Delay The browser prepares and paints the updated frame The drink is ready but has not reached the pickup counter yet Style recalculation, layout, paint, or delayed frame rendering

This breakdown matters because INP is not just a JavaScript metric. I often see teams reduce long tasks during load, improve Total Blocking Time, and expect field INP to follow. Sometimes it does. Often it does not, because the slow interaction is a filter change, menu open, route transition, or validation step that happens long after the page looks "loaded."

How scoring works

As DebugBear's metric reference explains, a good INP score is under 200 milliseconds, 200 to 500 milliseconds needs improvement, and anything above 500 milliseconds is poor. For a given page view, INP looks at the slowest qualifying interactions while ignoring a small number of extreme outliers. Across many real user visits, reporting then uses the 75th percentile. If percentile terminology causes confusion, this explanation of what percentiles mean in performance reporting gives the right mental model.

INP rewards pages that stay responsive throughout the session, not pages that only test well during startup.

That changes prioritization. A single expensive interaction buried deep in the funnel can hold back field INP even when your lab runs look respectable.

Understanding the Shift from FID to INP

A page can ace Lighthouse, post a better Total Blocking Time score, and still feel slow when someone opens a filter, submits a form, or taps through a client-side route change. That gap is the reason the shift from FID to INP matters.

FID only measured how long the browser waited before it could start handling the first interaction. It was useful for spotting startup congestion on the main thread, but it left out two things developers care about in practice: the work inside the handler, and the paint the user is waiting to see. It also ignored every later interaction on the page.

INP changes the target. It is based on real-user field data collected over time, and it reflects how a page responds across the session rather than at the first tap alone. That is a better match for how modern sites fail. The slowest interaction might come from a modal open, cart update, search refinement, or a widget injected by third-party scripts that block the main thread at the wrong time.

Interaction to Next Paint vs First Input Delay

Attribute First Input Delay (FID) Interaction to Next Paint (INP)
Scope First interaction only All qualifying interactions
What it captures Delay before handlers begin End-to-end interaction latency
Includes processing and paint No Yes
Best use Load responsiveness snapshot Overall UI responsiveness
Data source Narrower responsiveness view Field-based real user experience

This changes how performance work gets prioritized. Improving load-phase JavaScript can still help, but it will not fix field INP if the worst interaction happens later in the session. That is why teams sometimes celebrate lower lab blocking time and then wonder why CrUX or RUM data barely moves.

A page can feel fast on first input and still have poor INP because one expensive interaction later in the visit sets the score.

FID rewarded a good first impression. INP rewards sustained responsiveness. That is a stricter metric, but it is also closer to what users notice.

Identifying Common Causes of Poor INP

A page can post a respectable Lighthouse score, then still feel slow when someone opens a filter panel, changes a variant, or submits a form. That gap usually comes from work happening on the main thread during real interactions, outside the narrow window that lab tests emphasize.

INP gets dragged down by the single worst interaction in the session. In practice, that means the problem is often not initial load. It is a click handler, a render pass, or a layout update that blocks the browser long enough to delay the next paint.

A diagram illustrating five root causes for a poor Interaction to Next Paint (INP) score in web development.

Where the delay usually comes from

The pattern is usually straightforward. A user interacts. JavaScript runs too long, triggers too much rendering work, or forces the browser to recalculate layout across a large part of the page.

The usual offenders are:

  • Heavy event handlers that parse data, sort arrays, validate large payloads, or trigger broad state changes in one turn of the event loop
  • Framework re-renders that update a much larger subtree than the interaction requires
  • DOM and layout cost from large documents, expensive selectors, or forced synchronous layout after DOM reads and writes
  • Third-party scripts that compete for the main thread during input handling. If tags, chat widgets, or embeds are involved, this guide on reducing the impact of third-party code is a useful place to start

Rendering work is the part teams often miss. The handler may finish quickly, but if it causes a large component tree to re-render or invalidates layout across the page, the user still waits for paint. INP counts that wait.

Why teams misdiagnose it

Teams often chase what moved TBT in Lighthouse and expect field INP to follow. Sometimes it does. Often it does not.

A deferred script can improve startup. Edge caching can improve delivery. Code splitting can reduce load pressure. None of that fixes the interaction that happens 20 seconds later if clicking a size selector still kicks off expensive JavaScript and a large repaint.

That is why INP work tends to expose product-specific bottlenecks instead of generic page-speed issues. The slow path might be a cart drawer, a date picker, a faceted search update, or a personalization widget that only appears for some users.

If you want a broader frontend tuning reference alongside INP analysis, Nerdify's developer's guide to app performance covers many of the same rendering and JavaScript pressure points from a practical application perspective.

How to Diagnose and Optimize for Better INP

A page can post a decent Lighthouse score and still feel laggy when someone opens a filter, taps a size option, or submits a form 30 seconds later. That gap is where INP work usually starts. Lighthouse is useful for reproducing load-time pressure and spotting long tasks early, but field INP is set by the single worst interaction across the whole visit.

Start with field data, then reproduce the interaction in the lab. If you begin with Lighthouse alone, you often end up fixing startup work while the slow click that hurts INP happens later and never shows up in the test. A real user monitoring setup for Web Vitals gives you the missing view: which page, which device class, and which interaction pattern is failing for users.

Diagnose the interaction that users feel

Record a realistic flow in Chrome DevTools Performance panel. Skip the homepage-only trace. Open the drawer, change a variant, apply a filter, trigger the route change, and do it on a throttled mid-tier mobile profile if that matches your audience.

Then inspect the interaction in order:

  • Input delay: Was the main thread already busy before the handler could start?
  • Processing time: Did the event callback do too much synchronous work?
  • Presentation delay: Did the handler finish, but paint stall because rendering or layout work expanded afterward?

That breakdown matters because the fix changes with the bottleneck. A delayed handler points to contention. A long handler points to JavaScript execution. A late paint points to rendering cost, which is where many teams misread the trace.

If you need a broader frontend checklist beyond INP, Nerdify has a practical developer's guide to app performance that pairs well with this workflow.

Ask which interaction exceeded the user's patience threshold, on which device, and why that specific step could not paint sooner.

Optimize the part of the chain that is slow

Once the trace shows where time is going, target that stage directly.

Symptom Likely cause Better fix
Handler starts late Main thread contention Remove competing work, delay non-urgent tasks, yield between chunks
Handler runs too long Heavy synchronous JavaScript Split work, reduce callback scope, move expensive computation off the UI thread
Paint is delayed Large render or layout cost Shrink DOM updates, isolate components, avoid broad invalidation

A few changes consistently improve INP:

  • Yield during non-urgent work: Break up long tasks with setTimeout() or browser scheduling APIs so input can run sooner.
  • Keep handlers narrow: Do the minimum needed to show feedback immediately. Push analytics, secondary state updates, and cleanup work out of the hot path.
  • Use Web Workers where they fit: Parsing, transformation, and scoring logic can move off the main thread if they do not need DOM access.
  • Reduce rerender scope: If one click causes a large subtree to rerender, the framework is doing what you asked. The component boundary is still the problem.
  • Measure after each change: A lower TBT score is useful, but it does not prove the slowest in-session interaction improved.

A note for WordPress teams

WordPress stacks often hide interaction cost behind plugin combinations that look harmless in load tests. Theme JavaScript, sliders, consent tools, page builders, and add-on widgets can all compete during input. Caching, script delay, compression, and CSS optimization reduce background pressure, but they do not fix a slow cart drawer or filter panel by themselves.

Keep the optimization stack simple enough to test cause and effect. If multiple plugins overlap, it becomes hard to tell whether a change improved the interaction path or just altered the load trace.

A Modern Workflow for Monitoring INP

A page can post a decent Lighthouse score and still feel bad to use an hour later. Someone opens a filter panel, types into search, expands an accordion, and one interaction stalls long enough to become the session's INP problem. That is the disconnect teams miss when they treat INP like a load metric.

Screenshot from https://pagespeedplus.com

INP is judged in the field because the slowest interaction can happen anywhere on the page, not just during startup. Device speed, page state, late-running scripts, and the exact UI path all matter. Lab tools still help, but they help after field data shows where users are getting stuck.

What a useful monitoring loop looks like

The workflow that holds up in practice is simple:

  • Collect field data at the page and interaction level so you can see which URLs and UI patterns produce the worst delays
  • Segment by device, browser, and geography because a flow that feels fine on a fast desktop can break down on lower-end phones
  • Use DevTools to reproduce the interaction class after field data narrows the search space
  • Track regressions continuously so a new widget, experiment, or plugin update does not become the worst interaction on the page unnoticed.

A good real user monitoring setup for INP and Web Vitals closes the gap between "TBT improved in Lighthouse" and "the slowest real interaction still did not."

A video walkthrough helps if you want to see this kind of monitoring in practice.

The practical rule is to use lab data to reproduce and field data to prioritize. Lighthouse can point to long tasks during load. It cannot tell you which later interaction became the worst one for real users in-session. Once teams separate those jobs, INP work gets more focused and a lot less frustrating.


PageSpeed Plus helps you monitor real user INP, track regressions by URL and device, and pair monitoring with direct remediation through its WordPress plugin. If you want a cleaner workflow for diagnosing interaction delays instead of guessing from lab scores, take a look at PageSpeed Plus.