Frontend Performance/Core Web Vitals
Lesson 6 of 20 · Episode 6

Interaction to Next Paint (INP)

Responsiveness as a metric: input delay, processing, presentation — and how a busy main thread wrecks it.

INPResponsivenessMain threadYielding
Watch on YouTube ↗

Interaction to Next Paint measures the thing that makes a site feel alive: when you tap, type, or click, how long until the screen actually updates? It watches every interaction for the whole visit and reports the worst. Good is ≤ 200 ms; cross ~500 ms and the page feels broken.

See it for yourself

Feel a slow interaction

Turn up the background work — simulating JavaScript hogging the main thread — then tap the button. The “Done” state only appears after the interaction completes, so you literally feel the lag. Then flip the optimize switch and watch INP fall back into the green:

InteractiveINP live simulator
60%
Taps: 0

Crank up background work, then tap — feel the delay before “Done” appears.

Input delay · 180ms Processing · 170ms Presentation · 80ms
INP ≈430msNeeds workGood ≤ 200ms
Background work delays when the browser can even start your handler (input delay). Optimizing yields the thread and shrinks the work.
What's an 'interaction'?

An interaction is a group of events

From the user's view, they “clicked a button.” Under the hood, that fires a group of events — and INP measures the whole group plus the paint after it. INP only counts clicks, taps, and keystrokes; hover and scroll don't count:

InteractiveOne interaction → several events
one interaction →pointerdownpointerupclick

INP measures the whole group — every handler that fires for the interaction, plus the paint that follows. Each handler is a chance to do too much work. (Note: hover and scroll don't count toward INP.)

Each event can run its own handler. The slowest path through them all is what INP captures.
The anatomy

The three phases

Every interaction breaks into three phases — and the live demo above maps directly onto them:

  1. Input delay — from your tap until the browser is free to run the handler. Big when the main thread is busy.
  2. Processing time — running all the event handlers for the interaction.
  3. Presentation delay — recalculating layout and painting the next frame.
Key idea
Because JavaScript is single-threaded, a long task already running means your tap just waits. That wait is input delay — the most common reason interactions feel sluggish.
Why it replaced FID

INP vs the old FID

FID (old)INP (now)
What it measuresInput delay of the first interaction onlyFull duration of (nearly) every interaction
CoversJust the first tapThe whole visit
Catches late slowdownsNoYes (e.g. memory leaks)
Includes processing + paintNo, delay onlyYes

FID could call a site “responsive” off one fast first tap, even if it bogged down later. INP watches the whole session, so it reflects how the app actually feels over time.

What to actually do

Optimizing each phase

Input delay — yield the main thread

The thread is often busy with script evaluation (downloading, parsing, compiling, running JS) right when the user first interacts. Ship less JS, defer non-critical work, and break long tasks so the thread is free to respond.

Processing time — do less, and break it up

In the handler, do only the critical work (show the visual feedback the user expects) and push the rest — analytics, syncing, spell-check — into a later task so the paint isn't blocked:

render first, defer the rest
input.addEventListener("input", (e) => {
  updateTextbox(e);            // critical: user must SEE their text now

  setTimeout(() => {           // hand the rest to a later task
    updateWordCount();
    runSpellCheck();
    syncToServer();
  }, 0);
});

Presentation delay — paint less

A huge DOM makes every frame expensive. Keep the DOM lean, render only what's above the fold, and use content-visibility: auto to let the browser skip off-screen work.

Q1Sort each scenario
Which of these does INP measure?
Clicking a button
Typing in an input
Hovering over a menu
Scrolling the page
Q2Multiple choice
Your tap doesn't register because a long task is running. Which phase is to blame?
Q3Multiple choice
Why did INP replace FID?
Q4Multiple choice
In a keystroke handler, what should you do to keep INP low?
Key takeaways
  • INP measures responsiveness across the whole visit. Good ≤ 200 ms, poor > 500 ms.
  • It counts clicks, taps, keystrokes — not hover or scroll — and measures the whole event group + paint.
  • Three phases: input delay, processing, presentation.
  • It replaced FID, which only saw the first interaction's delay.
  • Fixes: yield the main thread, do less in handlers + break up tasks, keep the DOM lean.
← Previous
5. Cumulative Layout Shift (CLS)
Next →
7. RUM vs. Synthetic Monitoring