Optimizing INP: making every click feel instant
Break an interaction into input delay, processing time and presentation delay, find long tasks and long animation frames, yield to the main thread, cut hydration cost, debounce heavy work, skip off-screen rendering and use React transitions.
Comes up in: Web fundamentals, Frontend system design, React
Learn#
Raghav’s shop page loads fast, but “Add to cart” sometimes takes over half a second to show anything. Its INP is 600 ms, poor.
Interaction latency is the time from a click, tap or key press to the next paint that shows a response. It has three phases:
- Input delay: waiting for whatever task is already running on the main thread.
- Processing time: running your event handlers.
- Presentation delay: style, layout and paint of the result.
INP takes roughly the worst interaction of a visit, and 200 ms or less at the 75th percentile is good.
The main fix for long processing is to show feedback first, then do the rest later: update the button, yield to the main thread (JS.01.07), and continue with the heavy work in a new task so the browser can paint in between.
Call stack
- analytics.js (180 ms)
State
- input delay 180 ms
The user taps "Add to cart". An analytics script is running a 180 ms task, so the tap waits: input delay 180 ms.
Read the steps as text
- The user taps "Add to cart". An analytics script is running a 180 ms task, so the tap waits: input delay 180 ms.
- The click handler runs: it updates the cart and re-renders the whole product grid. Processing time 250 ms.
- Style, layout and paint of the changed grid take 170 ms more: presentation delay.
- Total 600 ms, poor. Fixes: defer analytics, update only the cart badge first and yield, render the grid in a transition.
Predict#
Predict first
A click handler takes 20 ms, but INP for that click is 350 ms. What is the most likely cause?
INP includes the wait before the handler and the rendering after it. Profiling only your handler misses both. Look for other long tasks, such as third-party scripts or hydration, and for large DOM updates.
Interview angle#
Say it like this — about 30 seconds
“An interaction’s latency is input delay, processing time and presentation delay. First I find the slow interactions from field data, with the web-vitals attribution build, then reproduce them in the Performance panel. For input delay I cut or split long tasks, such as third-party scripts and hydration. For processing, I show feedback first and yield, debounce expensive work, and use React transitions for heavy re-renders. For presentation delay I shrink DOM updates and use content-visibility for off-screen content.”
Follow-up What is the Long Animation Frames API?
Follow-up How does hydration hurt INP?
Follow-up Why update the UI before heavy work in a handler?
Practice#
Guided
Compute a visit’s INP the way the browser does, and find the dominant phase of an interaction.
Done when
- Latency is the sum of the three phases.
- INP skips one highest interaction per 50, otherwise it is the worst.
worstPhasenames the biggest phase.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
Name the three phases of an interaction.
Input delay, processing time, presentation delay.
Which interaction does INP report?
Roughly the worst one; one highest is ignored per 50 interactions.
What is the first fix for long processing in a handler?
Update the UI first, then yield and do the heavy work later.
Which API attributes slow frames to scripts in the field?
The Long Animation Frames (LoAF) API.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
Check yourself: What counts as a long task?
Any main-thread task over 50 ms.
How it works underneathSenior rounds
INP skips one highest interaction for every 50, so a long visit is not judged by a single outlier; most visits have fewer than 50 interactions, so the worst is reported Source: web.dev: Interaction to Next Paint.
Check yourself: Why does INP ignore some interactions on busy pages?
It skips one highest interaction per 50, so one outlier does not dominate long visits.
Edge cases and trapsWhere people slip
startTransition (RCT.02.03).Check yourself: How can React reduce processing time for heavy updates?
Mark non-urgent updates as transitions so urgent ones paint first.
In productionStaff-level answers
content-visibility: auto lets the browser skip off-screen sections, cutting presentation delay on long pages (WEB.02.02).Check yourself: Which CSS property cuts rendering of off-screen sections?
content-visibility: auto.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.