Interaction to Next Paint (INP) replaced First Input Delay (FID) as a Core Web Vital metric in March 2024. Through 2025 and into 2026, INP has become one of the most actionable performance metrics in technical SEO. Most sites score worse on INP than they did on FID because INP measures sustained responsiveness across the entire user session, not just the first interaction.

This guide explains what INP measures, why it matters, the common causes of poor INP scores, and the fixes that work in 2026.

Web performance metrics on screen

What INP measures

INP measures the latency between a user interaction (click, tap, key press) and the next visual update on the screen. The metric captures the 98th percentile of interactions during a page visit, meaning poor interactions later in the session also count toward the score.

Thresholds: Good INP is 200 milliseconds or less. Needs Improvement is 200 to 500 milliseconds. Poor is over 500 milliseconds.

The difference from FID: FID measured only the first interaction on a page. Once a user clicked something and the page responded, FID was done measuring. INP keeps measuring. If clicking a button works fine on page load but lags 600ms when clicked again after the user has interacted with several elements, INP catches it. FID did not.

Why most sites score worse on INP

FID was easy to optimise around. Defer non-critical JavaScript until after page load, and FID looked good. INP is harder because it requires the page to stay responsive throughout the session, not just at first load.

Common patterns we see in client audits:

Heavy JavaScript event handlers. Click handlers that run synchronous expensive operations (DOM rewriting, large array iterations, complex calculations) block the main thread when clicked.

Third-party scripts firing on interaction. Marketing pixels, chat widgets and analytics fire additional requests and execute scripts when users click certain elements, adding latency to the next paint.

React, Vue and similar framework re-renders. A click triggers a state update that causes a large component tree to re-render synchronously, blocking the main thread for hundreds of milliseconds.

Long animations that occupy the main thread. CSS transforms are fine, but JavaScript-driven animations (especially through libraries that calculate position manually) block paint.

Measurement tools

INP shows up across the standard performance tools:

PageSpeed Insights. Field data (real users) from Chrome User Experience Report (CrUX) shows actual INP across the last 28 days. Lab data shows estimated INP from a synthetic test. Field data is what counts for SEO.

Chrome DevTools Performance panel. Record a session, interact with the page, and review the timeline. INP-related interactions appear flagged. Drill into the main thread to find blocking scripts.

web-vitals JavaScript library. Embed in your site to capture real INP from real users. Send to your analytics platform for ongoing monitoring.

Real User Monitoring (RUM) tools. SpeedCurve, Calibre, DebugBear and others provide ongoing INP monitoring across your full site with alerting when scores degrade.

Diagnosing poor INP

The diagnostic workflow:

Identify the slowest interactions. PageSpeed Insights lists the worst INP interactions for a sample of users. Patterns usually emerge: form submissions, dropdown menus, search boxes, filter clicks on listing pages.

Reproduce the slow interaction locally. Open DevTools Performance panel. Record. Perform the interaction. Stop recording. Look for long tasks (over 50ms) in the main thread during and after the interaction.

Identify what is running on the main thread during the long task. Common culprits: large React component re-renders, third-party scripts firing on click, expensive JavaScript event handlers running synchronously.

Code optimization on monitor

Fixes that work

Break up long tasks. Any task running over 50ms on the main thread blocks paint. Split expensive operations using setTimeout(0), requestIdleCallback, or scheduler.postTask() to yield to the browser between chunks.

Defer non-critical work. When a user clicks a button, the visual response should be immediate. Defer analytics events, tracking pixels, and non-visual work until after the next paint. requestAnimationFrame helps here.

Use CSS animations instead of JavaScript. CSS transforms and opacity changes run on the compositor thread, not the main thread. Replace JavaScript-driven animations with CSS where possible.

Optimise React re-renders. Use React.memo for components that should not re-render on every state change. useMemo and useCallback for expensive computations and stable function references. React’s concurrent features (useTransition, useDeferredValue) let updates run without blocking high-priority interactions.

Lazy load third-party scripts. Chat widgets, marketing pixels, social embeds: load after the page is interactive, not before. Use the loading=”lazy” attribute or Intersection Observer to load on-demand.

Avoid layout thrashing. Reading layout properties (offsetWidth, getBoundingClientRect) immediately after writing styles forces synchronous layout calculation, blocking paint. Batch reads before writes.

Framework-specific patterns

For React: React 18+ concurrent features. useTransition for non-urgent updates. Suspense for code-split components. React Server Components for parts of the page that can render server-side. Move client-side state to URL parameters where possible to avoid re-renders.

For Vue: Async components for parts that do not need to be in the initial bundle. v-memo directive for expensive list renders. Watcher cleanup to prevent ghost reactivity.

For Next.js and Nuxt: Use the framework’s built-in code splitting per route. Image components for automatic lazy loading. Script component with strategy=”afterInteractive” for third-party scripts.

Third-party script management

Third-party scripts cause the majority of INP problems in our client audits. Common offenders:

Chat widgets (Intercom, Drift, Crisp). Load conditionally after user demonstrates engagement (scroll past first viewport, time on page over 30 seconds, click on relevant button).

Marketing pixels (Meta, TikTok, Pinterest). Move to server-side tagging through GTM server-side container. Client-side pixels become single lightweight requests instead of full script execution.

A/B testing tools (Optimizely, VWO). These often run synchronously to avoid flash of unstyled content. The price is INP impact. Either use the asynchronous loading option (with the trade-off of brief content shifts) or set strict timeouts.

Analytics platforms. GA4 has minimal INP impact when loaded correctly. Heavy analytics suites (Segment with many destinations enabled) impact INP more. Audit which destinations are actually needed and remove unused ones.

Server-side rendering and partial hydration

For sites built on React, Vue or similar frameworks, the largest INP wins often come from reducing client-side JavaScript:

Server-side rendering (SSR) reduces initial JavaScript execution because the page comes pre-rendered. Client just needs to hydrate.

Static site generation (SSG) reduces it further. No server-side computation per request.

Partial hydration (selective hydration in React 18, hydration islands in Astro) only hydrates interactive components, leaving static content as pure HTML. This dramatically reduces the JavaScript that runs on initial load.

Frameworks built on these patterns (Astro, Qwik, Fresh) often produce INP scores well under 100ms by default because there is simply less JavaScript to run.

Realistic targets

For a content-heavy site (blog, documentation): INP under 150ms achievable with disciplined script management.

For an ecommerce site (Shopify, WooCommerce): INP 200 to 350ms is normal. Under 200ms requires significant theme customisation and third-party script discipline.

For an interactive app (SaaS dashboard): INP 200 to 400ms is normal. Under 200ms requires careful framework optimisation and selective hydration.

The CrUX threshold for “Good” is 200ms. Hitting it consistently is a meaningful technical SEO achievement and a real user experience improvement.