Home Blog Next-Gen Web and Frontend De INP optimization techniques: interaction latency guide
Next-Gen Web and Frontend De March 26, 2026 8 min read

INP optimization techniques: interaction latency guide

Next-Gen Web and Frontend De Enterprise Guide 2026 SCALE D2C D2C Technology Next-Gen Web and Frontend De Enterprise Guide 2026 SCALE D2C D2C Technology

Interaction to Next Paint (INP) replaced First Input Delay as Google's responsiveness Core Web Vital in March 2024. Unlike FID which measured only the first input delay, INP measures the responsiveness of all interactions throughout the page lifecycle. Improving INP requires understanding the browser's event processing model at a deeper level than most performance guides address.

What Is INP?

INP (Interaction to Next Paint) is a Core Web Vital metric that measures the latency of a page's response to user interactions — clicks, taps, and key presses. Specifically, INP measures the time from when the user initiates an interaction to when the next frame is painted to the screen reflecting that interaction's visual response. INP reports the worst-case interaction latency observed during the page's lifetime (with some outlier exclusion for long sessions).

Definition
INP (Interaction to Next Paint) is a Core Web Vital that measures the time from a user interaction (click, tap, key press) to the next frame painted in response. Good INP is under 200ms. Needs Improvement is 200–500ms. Poor is over 500ms.
200ms
INP threshold for "Good" rating (Google)
37%
Of mobile web pages fail the INP "Good" threshold (CrUX data)
7%
Conversion rate improvement from 100ms INP improvement (Google study)

Anatomy of an INP Interaction

An INP measurement has three phases: input delay, processing time, and presentation delay.

⏱️
Input Delay
Time between the user's interaction and when the browser begins processing the associated event handlers. Input delay occurs when the main thread is busy with other tasks — long tasks, heavy JavaScript, or layout/style recalculation blocks event processing.
⚙️
Processing Time
Time spent executing the event handler code itself — the JavaScript that runs in response to the click or tap. This includes synchronous DOM manipulation, state updates, and any synchronous computations triggered by the event handler.
🖼️
Presentation Delay
Time from when event handlers finish to when the browser paints the updated frame. Includes style recalculation, layout, compositing, and rendering. Large DOM changes, forced reflows, or complex CSS recalculation extend this phase.

Core INP Optimisation Techniques

1. Break Up Long Tasks

The most common INP problem is long tasks on the main thread that delay event handler execution. The browser cannot process input events while a JavaScript task is running. Use scheduler.yield() (Chrome 115+) or the setTimeout(0) pattern to break long synchronous operations into smaller chunks, yielding control back to the browser between chunks:

// Modern approach using scheduler.yield()
async function processLargeList(items) {
  for (let i = 0; i < items.length; i++) {
    processItem(items[i]);
    // Yield to browser every 50 items
    if (i % 50 === 0) {
      await scheduler.yield();
    }
  }
}

// Fallback for browsers without scheduler.yield()
function yieldToMain() {
  return new Promise(resolve => setTimeout(resolve, 0));
}

2. Defer Non-Critical Work

Move work that doesn't need to happen synchronously in response to an interaction out of the event handler. Analytics tracking, logging, non-critical state updates, and secondary UI updates can be deferred using requestIdleCallback(), requestAnimationFrame(), or setTimeout():

button.addEventListener('click', (event) => {
  // Critical: update UI immediately
  updateCartUI(item);
  
  // Defer: analytics can wait
  requestIdleCallback(() => {
    trackAddToCart(item);
  });
  
  // Defer: server sync can happen asynchronously  
  queueMicrotask(() => {
    syncCartToServer(item);
  });
});

3. Minimise DOM Size and Layout Thrashing

Large DOM trees increase rendering time during the presentation delay phase. Layout thrashing — alternating between reading layout properties and writing DOM changes — forces the browser to recalculate layout synchronously, dramatically extending presentation delay. Read all layout properties first, then apply all DOM changes in a single batch.

⚠ Layout Thrashing Pattern to Avoid

element.style.height = element.offsetHeight + 10 + 'px' — reading offsetHeight forces layout; then the style.height write invalidates layout again. In a loop, this is catastrophic for INP. Always read all layout values first, store them, then write all style changes.

4. Use CSS for Animations Instead of JavaScript

CSS animations and transitions that only affect transform and opacity run on the compositor thread, separate from the main thread — they do not block event processing. JavaScript-driven animations that modify layout properties (width, height, top, left) run on the main thread and compete with event handler execution.

Framework-Specific INP Optimisation

FrameworkCommon INP IssueOptimisation
ReactSynchronous re-renders on every interactionuseDeferredValue, startTransition for non-urgent updates
ReactLarge component trees re-renderingReact.memo, useMemo, code splitting with React.lazy
VueWatchers triggering expensive computed re-computationMark non-reactive data with shallowRef/markRaw
AngularZone.js change detection on every eventOnPush strategy, NgZone.runOutsideAngular for non-UI work
Next.jsHeavy hydration blocking interactionsPartial hydration, React Server Components, Suspense boundaries

Measuring and Debugging INP

01
Chrome DevTools Performance Panel
Record a Performance trace during interactions. Look for long tasks (red bar above task) during the interaction window. The "Interactions" track shows INP timing. Use "Bottom-Up" tab to identify the specific JavaScript functions consuming most time.
02
web-vitals Library
Use Google's web-vitals library to measure INP in real user sessions: import { onINP } from 'web-vitals'. Log interactions above your budget to your analytics tool. INP reports need real user data — lab measurements do not capture the full distribution of interactions.
03
PerformanceObserver for Long Animation Frames
The Long Animation Frames API (LoAF) provides detailed breakdown of which scripts caused long frames. More detailed than Long Tasks API — shows script source, forced style/layout duration, and rendering time within each long frame.
04
CrUX and PageSpeed Insights
Google's Chrome User Experience Report (CrUX) provides real-user INP data aggregated by origin. PageSpeed Insights shows your site's real-user INP distribution from CrUX. Compare your INP to competitors using CrUX API for benchmarking.

Frequently Asked Questions

INP (Interaction to Next Paint) replaced First Input Delay (FID) as a Core Web Vital in March 2024. FID only measured the input delay of the very first user interaction after page load — a narrow metric that missed the vast majority of user interactions. INP measures the responsiveness of all interactions (clicks, taps, key presses) throughout the entire page lifecycle, reporting the worst-case interaction latency. This makes INP a much more comprehensive measure of a page's actual interactivity as users experience it during their session.

Google's INP thresholds are: Good — under 200 milliseconds; Needs Improvement — 200–500 milliseconds; Poor — over 500 milliseconds. For SEO purposes, achieving "Good" INP (under 200ms) across at least 75% of real user sessions (the 75th percentile from CrUX data) is the target. Note that INP measures the worst-case interaction in a session (with some outlier exclusion), so improving the slowest interactions has the most impact on the INP score.

The most common causes of high INP are: long tasks on the main thread that block event handler execution (input delay); expensive event handlers with heavy synchronous JavaScript (processing time); large DOM trees or layout thrashing that extend rendering time (presentation delay); third-party scripts that monopolise the main thread; heavy React re-renders triggered by user interactions; unoptimised CSS selectors that cause slow style recalculation; and animations implemented in JavaScript that modify layout properties rather than using GPU-accelerated CSS transforms.

scheduler.yield() is a browser API that allows JavaScript to yield control back to the browser's event loop during a long operation, allowing pending user input events to be processed before the JavaScript resumes. Without yielding, a JavaScript function that takes 500ms to complete will delay all user interactions by up to 500ms while it runs. By inserting await scheduler.yield() at safe break points in long operations, the browser can process pending click or keyboard events between chunks of work, dramatically reducing input delay. It is supported in Chrome 115+ with a polyfill available via setTimeout(resolve, 0) for other browsers.

startTransition and useDeferredValue in React 18 allow marking certain state updates as "non-urgent" so React can interrupt their rendering to process more urgent user interactions. Without these APIs, a user interaction that triggers a heavy re-render (filtering a large list, updating a complex chart) would block subsequent interactions until the render completes. With startTransition, React can pause the heavy render to process a new interaction immediately, then resume the render afterward. This maps directly to INP improvement by ensuring user interactions always trigger near-immediate UI feedback even when expensive rendering is in progress.

Layout thrashing occurs when JavaScript code alternates between reading layout properties (offsetHeight, getBoundingClientRect, scrollTop) and writing to the DOM, forcing the browser to recalculate layout synchronously multiple times within a single event handler. Each read after a write forces synchronous layout — a process that can take 10–100ms on complex pages. In a loop or across multiple components, this adds up to hundreds of milliseconds of avoidable layout recalculation in the presentation delay phase of INP. The fix is to batch all reads first (store them in variables), then apply all writes in a single batch, or use ResizeObserver for reactive layout calculations.

Use Google's web-vitals JavaScript library to measure INP in production: import { onINP } from 'web-vitals/attribution'. The attribution version provides detailed breakdown of which interaction caused the INP score, the event type, the interaction delay, and which element was interacted with. Send this data to your analytics tool (Google Analytics 4 natively supports Core Web Vitals, or send to Datadog, New Relic, or a custom endpoint). Lab measurements from Lighthouse are directionally useful but do not reflect real user INP — only CrUX data and real-user measurement capture the full distribution of user interactions.

Yes. INP is a Core Web Vital and is part of Google's Page Experience ranking signal. Google uses the 75th percentile INP from Chrome User Experience Report (CrUX) data for a given URL. Pages with "Poor" INP (over 500ms) are considered to have a poor page experience and may rank lower than equivalent content on pages with "Good" INP (under 200ms). The ranking impact is not the dominant factor in SEO — content quality and relevance still dominate — but for highly competitive queries where content quality is similar, Core Web Vitals including INP can be a tiebreaker.

INP OPTIMI

Ready to Implement INP optimization techniques: interaction latency g...?

Our specialist team delivers measurable ROI from Next-Gen Web and Frontend De programmes for enterprise and D2C brands.

Free Audit