Evaluat is in private access. Demos open through June. Book a slot
Learn · Concept

Interaction to Next Paint (INP), explained for engineers

Interaction to Next Paint replaced First Input Delay as a Core Web Vital in March 2024. It measures the slowest interaction your user had with the page. Here is what it captures, what causes it to spike, and how to test it under load.

Updated

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:

  1. Input delay. Time from the user action until the event handler starts running. This is whatever else the main thread was doing.
  2. Processing time. Time the event handler spent executing. Your code. Third-party code. Framework reconciliation.
  3. 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:

  1. 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() or requestIdleCallback.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

Common questions

FAQ

Why was First Input Delay (FID) replaced by INP?

FID only measured the delay before the browser started processing the first interaction. It did not measure the work itself or the time to repaint. A page could pass FID and still feel sluggish on every click after the first. INP measures the full latency of every interaction over the page session and reports the slowest.

What counts as an interaction for INP?

Pointer events (taps, clicks), keyboard events, and the resulting visual updates. Scroll and hover are not measured. The browser tracks input delay, processing time, and time to next paint for each interaction.

What is a good INP target?

Google's Core Web Vitals threshold is 200ms at the 75th percentile of users. Above 500ms is classified as poor. INP is harder to pass than FID was, because slow click handlers and main-thread work now count in full.

How do you measure INP in a synthetic environment?

Real-browser test scenarios are the only honest way. The scenario must perform the interactions you want measured (clicks, form fills, navigation taps), the browser records the full interaction latency, and the test report surfaces INP per session.

See it on your site

Test in real browsers.
Debug in real sessions.

Want to see this measured on your app?

30 minutes. We build a scenario on your real customer journey, run a small test, and walk you through the report with your data in it.

Sample report walkthrough
30s video · 16:9