Why INP Matters for Responsiveness
Interaction to Next Paint (INP) measures how quickly your page responds to user interactions. It captures the time from when a user first interacts with the page to when the browser can show a visual update. A low INP means your page delivers visual feedback quickly for most interactions.
INP becomes especially important in March 2024, when it replaces First Input Delay (FID) as the third Core Web Vital and begins affecting search rankings. The key reason INP is a stronger metric than FID is that it accounts for the full picture of user experience:
- FID only observes the first input in a page session; INP evaluates responsiveness across all user interactions.
- FID measures just the delay before the browser begins responding, while INP measures the time until the interaction's events complete.
- INP groups related events into logical interactions and defines latency as the maximum duration across all events in that interaction.

Since JavaScript runs on a single main thread by default, a page fetching a large script can't respond to anything until that thread frees up—even a click on a plain HTML link. Improving INP therefore means making the main thread available sooner for user input.
Selective Hydration with React 18
React 18's concurrent features—selective hydration and startTransition—were designed to improve interactivity. Concurrent React can prioritize what you interact with and can be interrupted by higher-priority actions.
When React and Next.js generate HTML on the server, that initial markup isn't interactive. The page only becomes usable after JavaScript loads and hydrates the components, attaching event handlers and other client-side logic.
In React 17 and earlier, hydration could not start until the JavaScript for the entire page was fetched. The source below shows the result:
// JavaScript for the entire page must be loaded
// before the page can become interactive
export default function HomePage() {
return (
<>
<Header />
<Body />
<Footer />
</>
);
}
JavaScript for the entire page must be loaded before the page can become interactive.
React 18 changes this by making hydration off the main thread and non-blocking—simply by wrapping components in a Suspense boundary. You no longer need to wait for all page JavaScript to load before hydrating any part of it. Components become interactive sooner, and the browser can interleave other work with hydration, reducing FID and INP.
import { Suspense } from 'react';
// Using a loading component as the Suspense fallback
function Loading() { ... }
// Using `Suspense` makes hydration non-blocking
export default function HomePage() {
return (
<>
<Header />
<Suspense fallback={<Loading />}>
<Body />
<Footer />
</Suspense>
</>
);
}
Using Suspense makes hydration non-blocking with React 18.
Case Study: nextjs.org
Using selective hydration with Suspense, the Next.js team cut the Total Blocking Time (TBT) of nextjs.org from 430ms down to 80ms, as measured by Lighthouse lab metrics. This approach also benefits related performance indicators like FID, Total Blocking Time, and Time to Interactive (TTI)—all of which depend on how quickly the main thread can process user input.



