How does Interaction to Next Paint differ mechanistically from First Input Delay in what it captures about main-thread responsiveness?

You passed FID comfortably — your 75th percentile was 40ms, well under the 100ms threshold. Then Google replaced FID with INP in March 2024, and your site suddenly failed. Nothing changed in your code. The metric changed. FID measured only the input delay of the first interaction on the page. INP measures the full processing duration of the worst interaction across the entire session, including input delay, event handler execution, and presentation delay. This is not a minor broadening of scope — it is a fundamentally different measurement that exposes responsiveness problems FID was architecturally incapable of detecting.

FID’s Structural Limitations and INP’s Session-Wide Measurement Scope

First Input Delay captured the time between a user’s first discrete interaction (click, tap, keypress) and the moment the browser began executing the event handler for that interaction. It measured exclusively the input delay phase — the duration the main thread was blocked by other tasks and could not begin processing the event. It did not measure how long the event handler took to execute. It did not measure how long the browser took to paint the visual result of that execution.

This meant a page with a 5ms input delay followed by a 500ms event handler execution registered an FID of 5ms — passing the 100ms “good” threshold comfortably despite delivering a half-second delay before any visual response appeared. The user experienced 505ms of total unresponsiveness, but the metric reported only the 5ms queue wait.

FID’s second structural limitation was its single-interaction scope. It captured only the first discrete interaction in each page session, ignoring every subsequent interaction regardless of latency. A page where the first click was on a pre-rendered navigation link (fast, minimal handler) but the third click triggered a complex product filter (slow, expensive handler) reported only the fast first click. The slow interaction that actually frustrated the user was invisible to the metric.

These two limitations — measuring only input delay and measuring only the first interaction — meant FID was a useful signal for initial page load blocking but fundamentally unable to assess ongoing page responsiveness. Google retired FID on March 12, 2024, replacing it with INP precisely because FID’s narrow scope gave a misleadingly positive picture of responsiveness on pages with complex interactivity.

INP’s Three-Phase Measurement: Input Delay, Processing, Presentation

INP measures three sequential phases for every qualifying discrete interaction (clicks, taps, key presses — but not scrolling, which is handled by the compositor thread independently of the main thread):

  1. Input delay: the time from when the user initiates the interaction to when the first event handler callback begins executing. This is what FID measured — the queue wait while other tasks occupy the main thread.
  1. Processing time: the time from when the first event handler starts executing to when the last event handler for that interaction completes. This includes all synchronous JavaScript execution triggered by the interaction — state updates, DOM manipulation, framework reconciliation, and any synchronous library calls.
  1. Presentation delay: the time from when event handler execution completes to when the browser paints the next frame that reflects the interaction’s visual result. This includes style recalculation, layout, compositing, and paint operations.

The sum of these three phases is the interaction’s total duration. INP observes all qualifying interactions throughout the entire page session and reports the interaction at approximately the 98th percentile of duration (specifically, for pages with 50 or more interactions, the worst interaction is excluded; for pages with fewer interactions, the worst interaction is reported directly). This near-worst-case selection ensures INP reflects the slowest interaction the user actually experienced, not an average or median.

Google sets the INP thresholds at 200ms or less for “good” and above 500ms for “poor.” The 200ms threshold is deliberately more demanding than the 100ms FID threshold, reflecting the broader measurement scope — 200ms across all three phases represents a higher standard than 100ms for input delay alone.

Why Event Handler Execution Time Is the INP Problem FID Never Revealed

Under FID, optimization efforts focused almost exclusively on reducing main-thread blocking before the first interaction. Deferring JavaScript with async and defer attributes, code-splitting initial bundles, minimizing Total Blocking Time during page load — these techniques reduced FID because they shortened the queue wait before the first event handler could begin executing.

These optimizations have minimal effect on INP failures caused by expensive event handlers that run during user interaction. A button click that triggers a synchronous DOM manipulation affecting 2,000 elements produces near-zero input delay (the main thread is idle when the user clicks, so the handler starts immediately) but 400ms of processing time as the framework reconciles the DOM. Under FID, this interaction did not register at all (it was not the first interaction) or registered as excellent (near-zero input delay). Under INP, it registers as 400ms — double the “good” threshold.

The Chrome team’s analysis of framework performance on INP confirms this pattern. In React applications, the rendering reconciliation triggered by state updates is the dominant contributor to processing time. A filter toggle that calls setState and triggers a re-render of a product grid with 200 items produces a long task that exceeds 200ms on mid-tier devices. Vue and Angular applications show equivalent patterns through their respective reactivity and change detection systems.

The optimization target shifts fundamentally: from pre-interaction blocking (reducing what the main thread is doing before the user acts) to in-interaction execution efficiency (reducing what happens while the event handler runs). This requires different tools and different architectural patterns — yielding APIs, concurrent rendering, web workers, and DOM surface area reduction rather than code splitting and deferred loading.

FID’s single-interaction scope meant that pages with fast initial loads but slow subsequent interactions appeared performant in the metric while frustrating users in practice. This gap was widest on pages with complex interactive behavior.

Dashboards with data visualization components passed FID because the first interaction was typically a navigation click or tab selection with minimal handler complexity. The fifth or tenth interaction — adjusting a date range filter that re-renders a chart with 10,000 data points — was invisible to FID despite being the interaction users experienced most frequently.

E-commerce SPAs with faceted search passed FID because the first interaction was a scroll or a simple category link. The filter checkboxes that triggered expensive product grid re-renders happened later in the session and were never captured.

Content management interfaces with rich text editors passed FID on the initial page load, but every keystroke during editing triggered processing that INP now measures.

INP captures the interaction pattern across the entire session. A page where 90% of interactions complete in 50ms but one interaction takes 600ms reports approximately 600ms as its INP (that worst interaction defines the 98th percentile). This session-wide scope is the primary reason INP failure rates are significantly higher than FID failure rates on identical codebases. The Cloudflare blog reported that many sites passing FID comfortably saw INP scores 3-5x worse than their FID equivalents when the metric was first made available for testing.

The Practical Consequence: Optimization Strategies Must Target Different Bottlenecks

FID optimization was synonymous with Total Blocking Time reduction during page load. INP optimization requires targeting the duration of the slowest event handlers during interaction — a fundamentally different engineering challenge.

The key tools for INP optimization that were unnecessary for FID include:

scheduler.yield() allows JavaScript to explicitly return control to the browser mid-task, enabling input processing and paint to occur between work chunks. Unlike setTimeout(0), which sends the remaining work to the back of the task queue (where third-party scripts may execute first), scheduler.yield() sends the continuation to the front of the queue, ensuring the deferred work resumes promptly after the browser processes pending paint and input events.

startTransition in React 18+ marks state updates as non-urgent, enabling the framework to break rendering into interruptible chunks. Each chunk yields to the browser between iterations, allowing paint frames to occur during what would otherwise be a single uninterruptible long task. Combined with useDeferredValue, this allows components to display stale data while fresh data is rendered in background chunks.

Web workers offload computation-heavy processing from the main thread entirely. For event handlers that perform data filtering, sorting, or calculation, moving the computation to a worker and posting the result back keeps the main thread free for paint and input processing. The worker runs on a separate thread with zero impact on INP.

AbortController enables cancellation of redundant work when a new interaction supersedes the previous one. A user rapidly clicking through filter options should not accumulate processing for all intermediate states. Aborting the previous filter computation when a new filter click arrives prevents processing time from compounding.

Code that passed FID without any of these techniques will likely fail INP on any page with complex interactive behavior. The architectural investment required for INP compliance is substantially larger than what FID demanded.

Does INP report the single worst interaction or an aggregate of all interactions?

INP reports a single value representing the interaction with the highest latency, with one exception: for pages with 50 or more interactions, INP ignores the single worst outlier and reports the second-worst. This near-worst approach prevents a single anomalous interaction from dominating the score while still capturing chronic responsiveness problems across the full session.

Are hover events included in INP measurement?

No. INP measures discrete interactions: clicks, taps, and key presses. Hover events, scroll events, and pointer movements are excluded because they do not represent deliberate user actions that expect a visible response. A slow hover-triggered tooltip does not affect INP, but a slow click handler on the same element does.

Does INP measurement continue after a single-page application navigates between views?

Yes. INP tracks interactions across the entire page lifecycle, including SPA soft navigations that change the visible content without a full page reload. All interactions from initial load through subsequent in-app navigations accumulate into a single INP score. This means a fast-loading SPA can still fail INP if route transitions or in-view interactions are slow later in the session.

Sources

Leave a Reply

Your email address will not be published. Required fields are marked *