Interaction to Next Paint (INP)
๐ Interaction to Next Paint (INP)
The Three Sub-Parts of an Interaction
INP measures the full round trip of an interaction, in three stages โ a parallel structure to Chapter 2's four-part LCP breakdown:
| Stage | What It Covers |
|---|---|
| Input delay | Time before the event handler even starts running |
| Processing time | How long the handler itself takes to run |
| Presentation delay | Time until the next frame is actually painted, showing the result |
INP reports a high-percentile value (around the 98th percentile, excluding a small number of outliers) across every interaction in the page's session โ reinforcing Chapter 1's FID-vs-INP point with the actual measurement behind it: one bad first click no longer defines the score, but neither does a good one.
Why a High Percentile, Not an Average
A single terrible interaction sticks in a user's memory even if most interactions felt fine โ averaging would wash that out. A high percentile deliberately keeps the worst realistic experience visible.
Every Interaction, Not Just the First
Unlike FID, a page that's fast on click one but sluggish on click fifteen will show that in its INP score โ nothing before this metric tracked that at all.
๐งต Why the Main Thread Is the Bottleneck
JavaScript execution, style recalculation, layout, and paint all compete for the same single main thread. If a long JS task is already running when a user clicks, the click's event handler can't even start until that task finishes โ directly inflating input delay.
Long Tasks
Any task occupying the main thread for more than 50ms is considered a "long task" โ the most common root cause of poor INP, detectable via the Long Tasks API.
Common Causes
Heavy synchronous JS, large third-party scripts (analytics, ads, chat widgets) running arbitrary code on the same thread, framework re-renders touching too much of the DOM, and expensive work done directly inline inside event handlers.
A Direct Link to Chapter 7
Expensive DOM queries or reflows running on every scroll event is exactly the debounce/throttle problem from JS Advanced, applied here at the whole-page level โ Chapter 7 covers this in depth.
Breaking Up Long Tasks
The fix is yielding to the main thread periodically during expensive work, so pending input and paint can be processed between chunks:
Blocking vs Yielding
setTimeout(fn, 0) is the classic yielding technique; requestIdleCallback suits lower-priority background work, and the newer scheduler.yield() offers a cleaner, purpose-built API for the same idea.
Felt Experience
Blocking
A click during the loop sits queued for hundreds of milliseconds โ visible, frustrating lag.
Yielding
The same total work completes, but the browser can slip the click's handler in between chunks โ it feels instant.
๐ป Coding Challenges
Challenge 1: Identify the Long Task
A button click triggers a function that loops over 10,000 array items doing synchronous work, taking 300ms total, before updating the DOM. Explain which INP sub-part this most directly inflates, and why.
Goal: Practice mapping a concrete code pattern onto the three-part INP breakdown.
Challenge 2: Chunk a Long-Running Function
Rewrite a function that synchronously processes 5,000 items in one pass into a chunked version using the pattern from this chapter, processing 100 items per chunk.
Goal: Practice applying the yielding pattern to a different chunk size and workload.
Challenge 3: Explain Why Percentile Beats Average Here
A page has 100 interactions in a session: 95 take 50ms and 5 take 800ms. Explain what the average would suggest about the page's responsiveness versus what a high-percentile INP score would show, and why the high-percentile view is more useful.
Goal: Practice reasoning about why INP's percentile design choice matters in a concrete case.
Third-party scripts โ analytics, ad networks, chat widgets, tag managers โ run on the exact same main thread as first-party code, and are extremely common, often dominant, contributors to poor INP. It's easy to profile and optimize a team's own event handlers while a marketing team's tag manager script quietly runs a 400ms long task on every page. Auditing INP means auditing every script actually running on the page, not just the ones a given team wrote โ third-party scripts are often added by other teams without engineering ever seeing their performance cost.
๐ฏ What's Next
With all three Core Web Vitals covered in depth, the next chapter turns to a concrete, high-impact fix for several of them at once: Image Optimization โ modern formats, responsive images, and lazy loading.