What is INP (Interaction to Next Paint)?
Interaction to Next Paint (INP) measures how quickly a page visibly responds to clicks, taps and key presses; good is 200 milliseconds or less.
Interaction to Next Paint (INP) measures how long a page takes to show a visual response after someone clicks, taps or presses a key. It became a Core Web Vital in March 2024, replacing First Input Delay, and it answers a simple question: when I do something, does the page react right away?
How it is measured
For each interaction, the browser times three phases up to the next painted frame:
- Input delay — the main thread is busy with other work, so your event handler has to wait.
- Processing time — your event handlers run.
- Presentation delay — the browser recalculates styles and layout and paints the result.
INP then reports one of the slowest interactions of the whole visit; on pages with many interactions it ignores one outlier for every 50. A single sluggish menu can therefore define your score. Scrolling and hovering don’t count. Full details are on web.dev: INP.
Thresholds
Good is 200 ms or less; poor is over 500 ms, measured at the 75th percentile of real visits. FID’s threshold was 100 ms, but it only measured the wait before the first handler started, which nearly every site passed. INP is stricter and much closer to what users feel.
What makes INP slow
- Long tasks — any JavaScript that blocks the main thread for more than 50 ms. Framework hydration, large analytics bundles and A/B testing scripts are frequent culprits.
- Heavy handlers that do everything synchronously — filtering 5,000 rows or re-rendering a whole page — before letting the browser paint.
- Very large DOMs, which make every style and layout pass expensive.
- Third-party tags loaded early and competing for the main thread; see render-blocking resources.
Example: respond first, work second
button.addEventListener('click', async () => {
showSpinner(); // visible feedback first
await scheduler.yield(); // let the browser paint
applyFilters(); // heavy work afterwards
});
scheduler.yield() is supported in Chromium-based browsers; where it isn’t, await new Promise(r => setTimeout(r, 0)) creates a similar break. The user sees a response at once, and the expensive work runs in a later task.
Common mistakes
- Trusting Lighthouse alone. A lab run can’t click your buttons, so it reports Total Blocking Time as a proxy. Real INP comes from field data.
- Checking only the homepage, while the slowest interactions live in filters, carts, search boxes and forms.
- Loading every script up front, including chat widgets and heatmaps nobody uses in the first seconds. Load them on demand or after the page settles.
- Ignoring mid-range phones. A handler that takes 40 ms on a developer laptop can take several times longer on a budget Android device.
Check it
The page speed test shows field INP from Google PageSpeed Insights when the URL has enough Chrome traffic, plus the number and weight of scripts on the page — usually the first thing worth trimming.
Frequently asked questions
Why does my page have no INP data?
INP needs enough real visits from Chrome users who share usage statistics, and those visitors must actually interact with the page. Low-traffic pages may only show origin-level data or none at all.
Does INP affect SEO?
INP is one of the Core Web Vitals that Google’s ranking systems use as part of page experience. Its influence is modest next to relevance, but poor responsiveness also hurts conversions directly.
How is INP different from Total Blocking Time?
Total Blocking Time is a lab metric that adds up main-thread blocking during page load. INP is a field metric based on real interactions. TBT is a useful proxy when testing, but only field data shows your actual INP.