INP > 200ms high
Interaction to Next Paint (INP) poor
Taps, clicks, and keystrokes feel laggy because the main thread is busy, pushing INP past the 200ms threshold.
What you see
Interaction to Next Paint (INP) 410 ms INP — Poor
What’s actually happening
You click a menu or type in a field and the screen takes a beat to respond. INP measures the delay from an interaction to the next visual update across the whole visit, reporting roughly the worst one. Good is 200ms or under; over 500ms is poor. It replaced FID as a Core Web Vital on March 12, 2024, and it's stricter — FID only measured input delay, INP measures the full round trip including the handler and the paint.
Common causes
- Long JavaScript tasks (>50ms) hogging the main thread when the interaction fires, so the browser can't respond until they finish
- Heavy event handlers doing layout reads/writes or large loops synchronously on click/input
- Excessive or unnecessary DOM work — re-rendering big lists, thrashing styles — before the next paint
- Large third-party scripts (tag managers, chat widgets, analytics) executing on the main thread
- Hydration of a heavy SPA/framework blocking interactivity right after load
How to fix it
- Catch the slow interactions in the fieldUse the web-vitals JS library (or the DevTools Performance panel with the INP marker) to log which interaction and which script caused the worst INP on real devices. Lab tools miss it because you have to actually interact.
- Break up long tasksFind tasks over 50ms in the Performance panel and split them. Yield to the browser with await scheduler.yield() (or setTimeout/requestIdleCallback) so input can be handled between chunks instead of waiting for one giant task.
- Lighten the event handlersDo only the minimum synchronous work on click/keydown to update the UI, then defer the rest. Debounce input handlers, avoid forced reflows (reading layout right after writing it), and don't re-render the whole list on every keystroke.
- Move work off the main thread or out of the wayPush heavy computation to a Web Worker, lazy-load non-critical third-party scripts, and code-split so you ship less JS to parse and execute up front.
- Give immediate visual feedbackIf an interaction must do real work, paint a cheap acknowledgment first (disabled state, spinner) so the next paint happens fast and the perceived lag drops even when the work continues.
Stop it recurring
Budget main-thread JS and total blocking time in CI, and load third-party tags through a façade or on-interaction so they can't stall every click.
Related errors