What INP measures
INP is a Core Web Vital. For every page session, the browser tracks the latency of every user interaction (taps, clicks, key presses) and reports the longest one as the INP for that session.
Interaction latency is measured end-to-end:
- Input delay. Time from the user action until the event handler starts running. This is whatever else the main thread was doing.
- Processing time. Time the event handler spent executing. Your code. Third-party code. Framework reconciliation.
- Presentation delay. Time from when the handler finished until the next frame paints with the result.
INP is the sum of those three, taken for the worst interaction in the session. A page that responds in 80ms to nine clicks and 600ms to one click has an INP of 600ms.
Why FID was replaced
First Input Delay only measured step 1 above, and only for the first interaction on the page. That made FID easy to pass: defer your scripts past first input, and the measurement looked fine.
The customer experience told a different story. The page felt responsive for the first click. The second click ran a heavy framework reconciliation. The third click triggered a layout-thrashing scroll handler. None of that showed up in FID.
INP closes the gap by measuring every interaction over the session and reporting the worst one. A page now has to stay responsive throughout, not just at first paint.
What pushes INP up
The usual culprits:
- Long event handlers. A click handler that runs synchronously through 80ms of work blocks the main thread, which blocks paint, which inflates INP. Break the work into smaller chunks with
scheduler.yield()orrequestIdleCallback. - Framework reconciliation on large trees. React, Vue, or Angular re-rendering a 500-node component synchronously after a click. Use concurrent features (React 18
startTransition, Vue Suspense) to deprioritise non-urgent updates. - Third-party scripts firing during interaction. Analytics SDKs, A/B testing libraries, chat widgets that listen on every click. They steal main-thread time at the worst possible moment.
- Layout work on the critical path. Click handlers that immediately read
offsetWidth, mutate the DOM, then re-read. Each read forces synchronous layout. The browser cannot paint until that resolves. - Large images decoded after click. A modal that opens with a 2MB hero image triggers decode work on the main thread. Use
decoding="async"and pre-decode where possible.
INP under load
Most teams measure INP in field data (CrUX, RUM) and call it done. That works for steady-state traffic. It does not work for capacity rehearsals, release validation, or any scenario where you need to know what INP will look like under load you have not yet served.
Synthetic INP measurement requires a real browser executing real interactions, because:
- HTTP-script tools cannot click anything. There is no DOM, no main thread, no interaction event to delay.
- Headless browsers without a full rendering pipeline skip presentation delay measurement.
- Shared-browser load testing models (where many virtual users live in one process) cannot measure INP accurately because the main-thread contention is artificial.
Real-browser load testing is the structural fit. Each virtual user is its own browser, with its own main thread. The scenario performs the click. The browser measures input delay, processing time, presentation delay, exactly as it would for a real user. The report gives you INP per session, per interaction, per URL.
INP and the third-party tax
Most teams discover their INP problem is a third-party problem. Analytics libraries that wrap every event. Consent banner SDKs that block clicks until they finish booting. Chat widgets that re-render on scroll.
The advantage of real-browser load testing here is that the network log and console log come back per session. You can sort sessions by INP, open the worst one, and see exactly which third-party request was firing on the slow click. It is the difference between knowing INP is bad and knowing which tag to renegotiate the contract for.
Common mistakes
- Measuring INP only at p50. The 75th percentile is the published threshold. The 99th percentile is your worst customers.
- Ignoring keyboard interactions. Form-heavy applications have INP problems that pointer-only testing misses.
- Testing INP with a single user. There is no main-thread contention. You will not reproduce the production problem.
- Counting on a long-tasks audit alone. Long tasks are a signal, not the measurement. INP is what you report.
INP is one of three Core Web Vitals. The companion metric for page render speed is Largest Contentful Paint, which measures when the biggest visible element finishes painting.