Back
Technology

INP Optimization Techniques for Web Developers

View source

Interaction to Next Paint (INP) is a Core Web Vital measuring responsiveness. This document outlines techniques to diagnose and fix INP issues.

Diagnosis

Measure INP in production using the web-vitals attribution build. The onINP function with reportAllChanges: true logs each candidate, including target element and event type.

Use Chrome DevTools Performance panel's Interactions track to visualize input delay, processing time, and presentation delay.

Common causes include heavy event handlers, third-party script blocking, layout thrashing, and large DOM size.

Fix 1: Break Up Long Tasks with scheduler.yield()

Tasks longer than 50ms block the main thread, increasing input delay.

Use scheduler.yield() with a setTimeout fallback to yield to the main thread between chunks.

Example: chunk a list rendering loop, yielding every 40ms to stay under the long task threshold.

Fix 2: Optimize Event Handlers

  • Debounce or throttle where appropriate, but note debouncing does not help click-driven INP.
  • Offload non-visual work (e.g., analytics) using requestIdleCallback with a setTimeout fallback, or Web Workers.
  • Use event delegation to reduce listener count: attach one listener to a parent and use event.target.closest().

Fix 3: Minimize Presentation Delay

Avoid layout thrashing by batching DOM reads before writes.

  • Reduce DOM size (target < 1400 elements) and virtualize long lists.
  • Use content-visibility: auto for off-screen content.
  • Use will-change: transform or opacity sparingly for composited animations.

Fix 4: Tame Third-Party Scripts

Audit third-party impact using DevTools' Third-party filter.

  • Use async, defer, dynamic imports, or facades to defer loading.
  • For heavy embeds, use the facade pattern (placeholder until user interaction).

Optimization Checklist

  1. Measure INP with web-vitals in production.
  2. Profile worst interactions in DevTools.
  3. Break long tasks >50ms with yielding.
  4. Move non-visual work out of handlers.
  5. Replace per-element listeners with delegation.
  6. Batch DOM reads/writes to avoid layout thrashing.
  7. Reduce DOM size and virtualize lists.
  8. Audit and defer third-party scripts.
  9. Apply content-visibility: auto.
  10. Re-measure after 28-day CrUX cycle; confirm 75th percentile INP ≤200ms.