Interaction to next paint: how to measure it and fix the slow interaction
Interaction to next paint measures how long a page takes to respond to a click, tap, or keypress, and the target is 200 milliseconds or less at the 75th percentile. Here is how to find the slowest interaction and fix the part that causes it.

Interaction to next paint measures how long a page takes to respond after someone clicks, taps, or presses a key, and the target is 200 milliseconds or less at the 75th percentile. Google defines it as a stable Core Web Vital that watches "the latency of all interactions a user has made with the page" and reports a single value that all, or nearly all, of those interactions stayed under (web.dev, read 2026-09-30). One slow interaction is enough to spoil the reading, and the slowness almost always sits in JavaScript you shipped.
Read this first
You need a page you can open in a browser, and access to a real-user source for your own numbers. This chapter covers responsiveness only. The loading half of the same report is a different metric: if your problem is the largest element painting late, largest contentful paint handles that one, and if you are still deciding whether any of this is worth doing, does page speed affect SEO settles that first. The measured side of this metric, how much blocking time 24 real homepages carry, is in total blocking time across 24 homepages.
What interaction to next paint actually times
The metric times one interaction from the moment the user acts to the moment the browser paints the next frame. That span is not a single number you can shrink in one place, because it is the sum of three parts, and each part fails for a different reason. Splitting the value before you change anything is the whole method; a change aimed at the wrong part leaves the total where it was.
| Part | What it covers | Usual cause |
|---|---|---|
| Input delay | From the input until the event handlers start | Long tasks already running on the main thread |
| Processing time | The event handlers themselves, start to finish | Heavy JavaScript inside the callback |
| Presentation delay | Handlers finished until the next frame paints | Layout, style, and rendering work that follows |
The metric watches clicks, taps, and key presses. It ignores scrolling, hovering, and zooming. It reports the worst interaction rather than the average, with one adjustment: on pages with many interactions, the single highest value in every fifty is dropped before the final number is taken, so a random hiccup on a busy page does not set the score. On most pages, and certainly on a small site, the one worst interaction is what gets reported.
The observer for this metric has real limits, and they explain most of the surprises. Event entries below 104 milliseconds are not reported by default, so register the first-input entry as well or a fast page may report nothing at all. A page restored from the back-forward cache resets its value, because users treat that as a fresh visit. And interactions inside an iframe are counted by the metric but not exposed to page JavaScript, which is one of the documented reasons a field number and a script can disagree.
Interaction to next paint is not the time your page took to load. It is the time it took to answer the one interaction a visitor remembers.
Why the target is 200 milliseconds, and not zero
There is no such thing as an instant response, so the threshold is empirical rather than absolute. Google sets good at 200 milliseconds or less, measured at the 75th percentile of page visits, with mobile and desktop counted separately. A quarter of your visits may be slower than the number you read; that is by design, because the percentile is what most of your visitors actually experience or better.
| Rating | INP value |
|---|---|
| Good | 200 ms or less |
| Needs improvement | Over 200 ms, up to 500 ms |
| Poor | Over 500 ms |
INP replaced First Input Delay, which only measured the delay before the first interaction was processed. INP measures the input delay, the full processing time, and the wait for the next frame, for every interaction, not just the first one. That is a stricter test, and it is why a page that once passed FID can still fail here.
Do it in this order
Four steps, each with a finishing condition you can check before moving on.
- Read the field number first, not the lab number. Real visitors are what the metric is defined on. Done when you can name your 75th-percentile INP for mobile and desktop separately.
- Find the slowest interaction. You need its element, its type, and its millisecond value before you can hypothesise. Done when you can write all three down.
- Split it into input delay, processing time, and presentation delay. Done when you can say which of the three dominates and point at the code responsible.
- Fix the dominant part only, then re-measure the same interaction. Done when that interaction drops and the field number follows.
The deliverable: one snippet, one threshold table, one fix list
The reliable way to collect the metric is not to write your own maths. The web-vitals library handles the percentiles, the back-forward cache case, and the background-tab case for you, and reports the same number the field tools use. Paste this into your page, or call onINP from your existing analytics.
import {onINP} from 'web-vitals';
onINP(({value, element, attribution}) => {
console.log('INP', value, element, attribution);
});
To watch every interaction as it happens, rather than only the final number, widen the Event Timing observer. The threshold has to be stated explicitly, and its floor is 16 milliseconds.
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 200) {
console.log(entry.duration, entry.name, entry.target);
}
}
}).observe({type: 'event', buffered: true, durationThreshold: 16});
Once you know which part dominates, the fix is usually one of three changes, and the wrong change is a common reason the number does not move.
| Where the delay sits | Fix |
|---|---|
| Input delay | Break up long tasks; defer or remove scripts that run on load |
| Processing time | Move heavy work out of the handler; batch DOM reads and writes |
| Presentation delay | Reduce layout scope; avoid large synchronous style work |
Two rules carry most of the weight. Keep any single task under 50 milliseconds, because that is the line past which the browser cannot yield to an input. And do not measure with your own laptop on a fast connection, because interaction delay is dominated by the device, not the network.
What we measured, and what it does not prove
Interaction to next paint cannot be produced without real users, so the closest a lab tool gets is total blocking time. We ran that on 2026-09-30: Lighthouse 13.5.0, mobile, on our own homepage, and querywin.com returned a total blocking time of 2,366 milliseconds. That is not an INP value and this chapter will not present it as one. It says the main thread was busy, not that a particular tap was slow, because a lab run with nobody on the page cannot produce an interaction to time. The number this metric is defined on is the field one, and we could not pull ours in this session. A low blocking time raises the odds of a low INP; it does not guarantee it.
Three ways this goes wrong
The first two waste a sprint. The third is the reason a team decides the metric is broken when it is their test that is.
- Optimising load instead of interaction. A faster first paint does not fix a handler that runs for 300 milliseconds. Measure the interaction before touching the bundle.
- Trusting a lab number for a field metric. Total blocking time can flag a problem that no user ever hits, and it can miss one that only appears when a real person interacts during load. Use it to reproduce, not to conclude.
- Fixing the wrong part. Rewriting a handler does nothing for a delay that comes from a long task that started before the click. Split the value first, or the work lands in the wrong place.
Common questions
Is interaction to next paint a ranking factor?
It is a Core Web Vital, which Google lists as one input among many, and we will not present it as more than that. The honest reason to fix it is that a page which answers in under 200 milliseconds keeps more of the people who reach it.
What is a good interaction to next paint score?
200 milliseconds or less, at the 75th percentile of visits, with mobile and desktop counted separately. Over 500 milliseconds is poor, and anything between needs improvement.
Why is my interaction to next paint different from my total blocking time?
They measure different things. Blocking time sums every long task during load and needs no interaction at all, while INP needs a real interaction and reports the worst one. Blocking time is a lab proxy, not a substitute.
Does INP apply to desktop traffic?
Yes, but the two are scored separately, and a page that passes on a fast desktop can still fail on a mid-range phone. Devices drive this metric far more than bandwidth does.
Next step
Responsiveness is one of three parts of the page experience picture, and it is the one most teams measure last. If you only take one thing from this chapter, take the loop: read the field number, find the slowest interaction, split it into three parts, fix the largest, measure again. Doing that on the pages visitors actually land on is part of what QueryWin works on.
Part of the QueryWin handbook · Level 2


