INP Optimization: The Complete 2026 Guide
Pass INP under 200ms with concrete fixes. Long task breaking, event handler patterns, hydration cost, and framework-specific INP wins.
Interaction to Next Paint replaced First Input Delay as a Core Web Vital in March 2024, and two years later it is the metric most sites still fail. As of early 2026, 43 percent of tracked sites do not pass the 200ms INP threshold, making it the single most-failed Core Web Vital across the web. The penalty has bite. Sites with INP between 200ms and 500ms (the "needs improvement" range) lose an average 0.8 ranking positions on competitive queries. Sites above 500ms (the "poor" range) lose 2 to 4 positions.
This guide walks through INP from first principles, then through the concrete fixes that move the metric. The three INP stages and which one your bottleneck lives in. Long tasks and how to break them. The scheduler.yield() API and the older patterns it replaces. Hydration cost and the islands architecture answer. Framework-specific patterns for React 19, Vue, Svelte, and Astro. The third-party script audit that surfaces silent INP killers. The goal is to pass INP under 200ms with real fixes, not generic advice.
Quick Answer
Pass INP under 200ms in 2026 by identifying long tasks (greater than 50ms) blocking the main thread, breaking them with scheduler.yield() or setTimeout, reducing hydration cost via islands architecture or careful React 19 patterns, auditing third-party scripts (Google Tag Manager, chat widgets, analytics) for INP impact, and measuring in the field with web-vitals.js. 43 percent of sites currently fail INP, and the failure penalty averages 0.8 ranking positions on competitive queries.
Key Takeaways
- 43 percent of sites fail the 200ms INP threshold per early 2026 CrUX data
- INP has three stages: input delay, processing time, presentation delay
- Tasks over 200ms are problem candidates, over 500ms are confirmed problems
- Third-party scripts (GTM, chat widgets, analytics) commonly add 200ms plus per interaction
scheduler.yield()is the modern way to break up long tasks- Islands architecture reduces hydration cost dramatically versus SSR full hydration
INP Versus FID and Why the Metric Is Stricter
INP replaced First Input Delay in March 2024, and the change was not cosmetic. FID measured the delay before the first user interaction's event handler started. INP measures the latency of every interaction throughout the page lifecycle and reports the worst (or near-worst) value. The metric is harder to pass because it catches problems FID never measured.
The FID era let sites get away with a fast first interaction followed by slow subsequent interactions. A page could pass FID with a clean initial load, then become unresponsive as the user scrolled, clicked, and typed. INP catches all of that. The reported INP is typically the 98th percentile interaction latency across the page session, so any one bad interaction can fail the metric even if the rest were fast.
The threshold values are 200ms (good), 500ms (needs improvement boundary), and above 500ms (poor). Google's CrUX dataset reports per-page INP, and the per-page value is what feeds into the Core Web Vitals signal Google uses for ranking. Sites that pass INP at the 75th percentile of page loads pass the metric. Sites that fail at the 75th percentile fail. Our glossary entry on INP fundamentals covers the metric definition for readers new to the topic.
The strictness shows up especially on JavaScript-heavy sites with significant hydration cost or third-party script overhead. A site that passed FID comfortably can fail INP badly because the hydration phase plus third-party scripts plus app-level event handlers stack up. This is the structural reason 43 percent of sites still fail INP two years after the metric became official. The broader Core Web Vitals framework covers LCP, INP, and CLS together if you need the full context.
The Three INP Stages: Input Delay, Processing, Presentation
Every interaction passes through three stages, and the INP value is the total of all three. Knowing which stage is your bottleneck determines which fix to apply, and most teams skip this diagnostic step and apply random fixes that miss the actual problem.
Stage one is input delay. The time from when the user actually performs the interaction (clicks, taps, types) to when the event handler starts executing. Input delay is dominated by main thread activity. If the main thread is busy running a long task when the user clicks, the click event waits until the task finishes. Input delay is the most common bottleneck on JavaScript-heavy pages.
Stage two is processing time. The time the event handler itself spends executing. Processing time is dominated by the work the handler actually does. Updating state in a framework, calling an API, computing derived values, mutating the DOM. Processing time is the most common bottleneck on pages where the event handler does substantial work in a single synchronous block.
Stage three is presentation delay. The time from when the event handler finishes to when the browser repaints with the updated state. Presentation delay is dominated by layout recalculation, paint, and (for framework apps) framework re-render and reconciliation. Presentation delay is the most common bottleneck on pages with large component trees that re-render on every interaction.
The diagnostic workflow is to record an interaction in Chrome DevTools Performance panel, locate the INP entry in the Interactions track, and look at the stage breakdown. The stage with the largest contribution is your fix target. Trying to fix presentation delay when your bottleneck is input delay produces no measurable improvement and burns hours that could have been spent on the right fix.
Long Tasks: Identifying and Breaking Them
Long tasks are tasks on the main thread that run for more than 50ms. They block input processing for the duration of the task, so any long task during user interaction time pushes input delay up directly. Tasks above 200ms are INP problem candidates, tasks above 500ms are confirmed INP problems.
Identifying long tasks requires the Long Tasks API or the Performance panel's Bottom-Up view. The Long Tasks API exposes long tasks programmatically and is the right choice for production monitoring. The Performance panel is the right choice for local debugging because it shows the call stack that produced the task, which is what you need to know to fix it.
The fix categories for long tasks are three. First, decompose the task into smaller chunks (each chunk under 50ms) and yield to the main thread between chunks. Second, move the work off the main thread to a Web Worker if the work does not touch the DOM. Third, defer the work entirely to an idle moment via requestIdleCallback.
The decomposition pattern is the most common and the most useful. The modern API for decomposition with main thread yielding is scheduler.yield(), which is available in Chrome 129 plus and approximately 80 percent of users in early 2026. Polyfilled patterns using setTimeout(0) or await new Promise(r => setTimeout(r, 0)) work in older browsers but are slightly less performant than scheduler.yield() because the polyfill paths trigger task creation overhead.
Yielding to the Main Thread (scheduler.yield and Friends)
The scheduler.yield() API is the cleanest way to break a long task into chunks that allow the main thread to handle pending input. The API returns a promise that resolves after the browser has processed any pending tasks, including input events, so awaiting it gives the user interaction priority.
The pattern looks like a normal async function with await scheduler.yield() inserted between work chunks. A task that previously ran 300ms in one block can be split into six 50ms chunks with yields between them. The total work time is the same. But because input gets handled between chunks, the INP impact is dramatically reduced.
For browsers without scheduler.yield() (the remaining 20 percent in early 2026), the fallback pattern uses setTimeout(0) or the older await new Promise(r => setTimeout(r, 0)). The functional behavior is similar (yield to the event loop, allow pending tasks to run) but the overhead is higher because each setTimeout(0) schedules a new task rather than just yielding within the current task. A feature-detection wrapper that uses scheduler.yield() where available and falls back to setTimeout(0) covers all cases.
The mental model that helps is to think of any chunk of work over 50ms as a candidate for splitting. The exact split point depends on the work but the rule of thumb is one yield per logical unit of work. Process a batch of items, yield, process the next batch, yield. Render a component tree, yield, render the next component tree. The pattern is mechanical once internalised.
Hydration Cost and the Islands Pattern
Hydration is the process of taking server-rendered HTML and attaching JavaScript event handlers, state, and behavior to it client-side. Full hydration (the default in most SSR frameworks) walks the entire component tree and attaches handlers to everything, even components the user will never interact with. The hydration phase is a long task or series of long tasks on JavaScript-heavy pages, and it directly inflates INP.
The islands architecture, popularised by Astro and now adopted by other frameworks, hydrates only the components that need interactivity, leaving the rest as static HTML. A landing page might have a header search box, a CTA button, and a video player as the only interactive islands, with the rest of the page (hero text, marketing sections, footer) staying static. Hydration cost on an islands page is typically 5 to 20 percent of equivalent SSR full-hydration page.
The INP impact of the shift is substantial. Sites migrating from SSR with full hydration to islands architecture commonly report INP improvements of 30 to 60 percent on the first measurement after migration. The improvement comes mostly from input delay reduction, because the hydration phase that previously blocked input now does much less work.
For sites that cannot migrate to islands architecture, partial hydration or progressive hydration patterns in React 19, Vue 3.4 plus, and SvelteKit deliver similar benefits with more incremental work. The key insight is that any reduction in hydration scope reduces INP, and the reduction compounds across every page load. Our JavaScript SEO guide on SSR and islands covers the architectural tradeoffs in more depth.
Framework Specific Patterns (React 19, Vue, Svelte, Astro)
Each major framework has specific patterns that help or hurt INP. The framework-agnostic advice (break long tasks, yield to the main thread) applies everywhere, but the framework-specific advice often delivers larger lifts because it addresses where the long tasks originate.
For React 19, the key APIs are useTransition, useDeferredValue, and React.memo. useTransition marks state updates as non-urgent so React processes them between input events instead of synchronously. useDeferredValue lets you render a stale version of a value while the latest version computes in the background. React.memo and the useMemo/useCallback hooks prevent unnecessary re-renders that contribute to presentation delay. The new React Compiler (released in 2025) automates many of these optimisations and is worth adopting if you can.
For Vue 3, the key APIs are v-memo, async components, and computed properties. v-memo skips re-rendering of memoized regions when dependencies have not changed. Async components defer their JavaScript loading until they are actually needed. Computed properties cache derived values and avoid recomputing on every render. Vue 3.4 plus includes Suspense improvements that help with hydration scheduling.
For Svelte, the framework's compile-time reactivity model means much of the INP work is automated. The remaining manual patterns are {#await} blocks for deferred component loading, the <svelte:options compatibility/> flag for the compiler's bundle-size optimisations, and judicious use of tick() to schedule updates after the next microtask.
For Astro, the default static output has near-zero INP cost since there is no client-side JavaScript on most pages. The patterns that matter for Astro are the client: directive choices (client:idle for non-critical interactivity, client:visible for below-fold interactivity, client:only for components that should not render server-side at all), and the view-transitions integration that handles SPA-like navigation without the full hydration cost.
Third Party Script Audit (The Silent INP Killer)
Third-party scripts are the most common silent INP killer. A site with clean first-party code can still fail INP because of accumulated third-party overhead. Google Tag Manager loading 8 tags plus an Intercom chat widget plus HubSpot tracking plus Facebook Pixel plus a cookie consent tool can easily add 200ms or more of processing overhead to every interaction. The diagnostic is straightforward but most teams skip it.
The audit workflow runs in three steps. Step one is Coverage panel in Chrome DevTools. Open the page, record coverage, interact normally. The Coverage panel shows which scripts are loaded and how much of each is actually used. Scripts with low utilisation (below 30 percent) are candidates for removal, lazy loading, or replacement.
Step two is Performance panel with the Bottom-Up view. Record a session of normal interaction. In the Bottom-Up view, sort by total time and look for third-party domains in the top entries. Any third-party script accounting for more than 5 percent of main thread time is a significant INP contributor.
Step three is the per-tag breakdown for Google Tag Manager specifically. GTM is often a major contributor on enterprise sites because it bundles many third-party tags into a single container. The GTM Preview mode plus the DebugBear GTM audit workflow lets you measure each tag's individual contribution and decide which to keep.
The fix categories for third-party scripts are four. First, remove the script entirely if it is not delivering measurable business value. Second, defer the script's loading to after the interactive window using defer, async, or dynamic loading on user interaction. Third, replace heavy scripts with lighter alternatives (often the official documentation lists lightweight versions). Fourth, move the script to a Web Worker via Partytown if the script is essential and cannot be lightened.
Measuring INP in the Field With web-vitals.js
Lab testing in DevTools surfaces structural problems but misses the real-world INP your users actually experience. Field measurement via web-vitals.js is required to know your actual INP distribution and to track improvement over time.
The web-vitals.js library is the canonical client-side library for measuring Core Web Vitals. It is maintained by the Chrome team and tracks LCP, INP, CLS, FCP, and TTFB. Implementation is one script tag plus a callback that sends each metric to your analytics endpoint of choice (Google Analytics, custom backend, third-party service like SpeedCurve or DebugBear).
The implementation pattern for INP specifically is onINP(callback) which fires once per page load with the final INP value. Send the value to your analytics with the page URL and any relevant context (device type, connection type, user segment). Aggregate by the 75th percentile per page to compare against the CrUX threshold Google uses.
The field data is what should drive prioritisation. A page with a synthetic INP of 180ms but a field 75th-percentile INP of 350ms is failing in the wild and needs work. A page with a synthetic INP of 250ms but a field 75th-percentile INP of 150ms is passing in the wild and is lower priority. The synthetic measurement is a sanity check, the field measurement is the truth.
Before and After INP Case Study
The typical INP optimisation project on a moderately complex site (CMS-driven blog with a few interactive components, third-party analytics, chat widget) follows a predictable curve. The starting point is often 300 to 500ms INP at the 75th percentile, with the bottleneck split across hydration cost and third-party scripts.
The first round of fixes targets third-party scripts. Removing one unused analytics, deferring two scripts to user interaction time, and switching the chat widget from auto-load to user-triggered typically drops INP by 40 to 80ms. Time investment is a few hours. Risk is low because the changes are reversible.
The second round of fixes targets long tasks in first-party code. Identifying the three to five worst long tasks in the Performance panel and adding scheduler.yield() between work chunks typically drops INP another 30 to 60ms. Time investment is a day or two depending on framework. Risk is moderate because the changes touch core code paths.
The third round of fixes targets hydration cost. Moving from full SSR hydration to selective hydration (or islands for greenfield rewrites) typically drops INP another 50 to 150ms. Time investment is a week or more depending on framework and scope. Risk is higher because the change affects the rendering architecture.
By the end of the three rounds, a site starting at 350ms typically lands around 150ms at the 75th percentile, comfortably passing the 200ms threshold. The ranking impact is visible within 2 to 4 weeks of the field measurement crossing the threshold, as Google's CrUX aggregation re-evaluates the site's Core Web Vitals signal.
FAQ
What Is a Good INP Score in 2026?
200ms or below at the 75th percentile of page loads is the "good" threshold. 200ms to 500ms is "needs improvement". Above 500ms is "poor". The 75th percentile is what Google's CrUX dataset uses for the Core Web Vitals ranking signal.
How Long Does It Take for INP Fixes to Affect Rankings?
Field data is what feeds the ranking signal. The CrUX dataset Google uses aggregates over 28 days, so most INP fixes take 4 to 8 weeks to fully reflect in your CrUX measurement. Ranking impact follows after that, typically visible within an additional 2 to 4 weeks.
Do I Need scheduler.yield or Can I Use setTimeout?
scheduler.yield() is preferred where available (Chrome 129 plus, roughly 80 percent of users in early 2026) because it has less overhead than setTimeout(0). For older browsers, setTimeout(0) is the established fallback. A feature-detecting wrapper covers both cases cleanly.
Will Removing All My Third-Party Scripts Fix INP?
Often yes, but rarely an option. The realistic goal is to audit and remove the scripts that do not deliver business value, defer the ones that do, and lighten the rest. Aggressive removal is usually possible without losing analytics, advertising, or chat functionality, but requires per-script auditing.
Does Astro Have Better INP Than React or Vue Out of the Box?
For static-output Astro pages with no client-side JavaScript, yes by a large margin. For Astro pages with islands, the INP is comparable to a well-optimised React or Vue page with partial hydration. The difference is that Astro makes the partial-hydration pattern the default rather than something teams have to deliberately implement.
How Often Should I Audit INP?
For sites with active development, monthly is the right cadence. The audit includes pulling field INP data, comparing against the previous month, and investigating any pages that regressed. Quarterly is the minimum for sites with less active development.
Can a CMS Theme Cause INP Failures?
Yes, and this is the most common cause on CMS-driven sites. Heavy WordPress themes or page builders that load extensive JavaScript on every page commonly fail INP. The fix is often theme selection or a lighter page builder rather than per-page optimisation, because the JavaScript overhead is structural.
Wrap Up
INP optimisation in 2026 is mostly a methodical engineering problem. Identify the bottleneck stage (input delay, processing, presentation). Find the long tasks that contribute most. Break the tasks with scheduler.yield(). Reduce hydration cost via islands or partial hydration. Audit and trim third-party scripts. Measure in the field. The work is straightforward once you have the diagnostic in place, and the ranking lift from passing INP is real and consistently visible.
The 43 percent of sites still failing INP in early 2026 are the sites that have not done the diagnostic work. The 57 percent that pass have either built on architectures that naturally produce low INP (static-first, islands, careful SSR) or have invested in the optimisation work over the past two years. Astro SEO Blog has tracked INP optimisation projects across reader sites and our own, and the consistent finding is that the first round of fixes (third-party scripts plus the worst long tasks) usually drops INP by 30 to 50 percent and takes one to two engineering days. The work scales from there, but the first round alone gets most sites into the passing range. Start there.
Related Articles
Crawl Budget Optimization for Large Sites
Stop wasting Googlebot on filter URLs and redirect chains. Sitemap discipline, robots.txt patterns, and AI bot competition mitigation.
How to Fix Indexing Issues in Search Console
Resolve Discovered, Crawled, and Page with redirect statuses. URL Inspection workflow, quality fixes, and what to deliberately leave unindexed.
How to Fix Keyword Cannibalization in 2026
Diagnose and resolve internal keyword competition. Search Console workflow, intent audit, and decision tree for merge, redirect, or differentiate.