Interaction to Next Paint (INP) measures responsiveness: when a visitor taps, clicks or presses a key, how long until the page paints a visible response. Rather than timing a single interaction, INP looks at all interactions during the visit and reports one of the slowest, so it describes how the page feels the whole time, not just at load. It became a Core Web Vital on 12 March 2024, replacing First Input Delay (FID).
What it actually times
Each interaction has three parts: input delay (waiting for the main thread to be free), processing time (your event handlers running), and presentation delay (the browser laying out and painting the result). INP spans the whole distance from input to the next frame. A high figure almost always means the main thread was busy running JavaScript.
That span is the whole reason the metric changed. First Input Delay, which INP replaced, timed only the first of those three parts, and only on the first interaction of the visit. A page could pass FID comfortably while feeling frozen, because everything the visitor actually notices, the handler running and the screen changing, happened after FID had stopped counting. There is no separate entry for FID in this glossary for the same reason Google retired it: what it measured is now the first third of the number above.
The one metric we cannot measure for you
Every number published on this site comes from a lab run: a simulated load, at a fixed viewport, that never taps anything. That makes our audit base structurally blind to INP. We have no INP figure for any of the sites we have audited, and we will not print an estimate as though it were one.
What we report instead is TBT, which is what Lighthouse itself substitutes. It is a
reasonable proxy for load-time responsiveness and a poor one for the rest of the visit, since
it stops measuring once the page settles. For a real INP figure you need field data: Search
Console’s Core Web Vitals report, the CrUX dataset, or your own web-vitals instrumentation
on live traffic.
The bar, and who it is measured on
The Good / Needs-work / Poor bands sit in the summary panel. INP is graded at the 75th percentile of real visits, so a page passes only when three in four interactions respond that fast.
What makes a page slow to answer
- Heavy event handlers running long tasks on the main thread. The browser cannot paint
the next frame until your handler returns, so a slow
clickhandler is felt directly. - Large third-party scripts competing for the thread. Analytics, chat widgets and tag managers keep the main thread busy, delaying the response to every interaction.
- Doing all the work synchronously on click. Running the full computation before showing anything leaves the visitor with no feedback.
- Booting more JavaScript than the page needs. Hydrating framework code the interaction never uses steals thread time from the interactions that matter.
- Layout thrash inside handlers. Reading and writing layout in the same handler forces synchronous reflows that stretch the interaction out.
The price of clearing the thread
- Deferring and lazy-loading interactive code clears the thread, but the first use of a deferred feature is slower, because it loads on demand at click time.
- Yielding mid-task with
scheduler.yield()trades throughput for responsiveness: the work finishes a frame later, the page answers immediately. - Over-deferring pushes the work into TTI. The page looks ready before it is wired up, so an early tap lands on a control that is not listening yet.
Our own compromise is to defer third-party scripts to the first real interaction and re-run them on wake, so a feature is ready by the moment a visitor reaches for it.
Keeping the interaction path clear, in code
- <script src="/widgets.js"></script>
+ <script src="/widgets.js" defer></script>
Inside a heavy handler, paint a cheap response first, then yield so the browser can render before the expensive work starts:
btn.addEventListener('click', async () => {
showFeedback(); // cheap, visible immediately
await scheduler.yield(); // let the browser paint
doExpensiveWork(); // the rest, off the critical interaction
});
Where our levers actually land
WebSpeed defers third-party scripts until the first real interaction and re-runs them on
wake, queues jQuery ready() callbacks instead of firing them all up front, and delays
non-critical inline scripts. Those moves clear the main thread during load. Whether they
reached your visitors is a question only field data can answer.