Chapter 60: Core Web Vitals & Performance Engineering

Interaction to Next Paint (INP)

Comprehensive responsiveness engineering: Replacing FID, the 3 sub-parts of interaction latency, and measuring the 98th percentile interaction.

LEARNING OBJECTIVES
  • Understand why Interaction to Next Paint (INP) officially superseded First Input Delay (FID) as a Core Web Vital.
  • Identify all user input types tracked by INP (clicks, taps, keypresses) vs. compositor-driven gestures (scrolls, hovers).
  • Master the 3 sub-parts of interaction latency: Input Delay, Processing Duration, and Presentation Delay.
  • Learn how browsers calculate session-level INP across short vs. long user journeys (the 98th percentile outlier rule).
  • Instrument and debug interaction latencies using the Event Timing API and PerformanceObserver.
🎬 INTERACTIVE VISUAL PIPELINE Core Architecture Simulation
🌐
1. Input
Directives & Tags
⚙️
2. Parse
Tokenizer & AST
🌳
3. Layout
Box Model & Flow
🎨
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.

📖 The Mental Model & Story (Intuitive Foundation)

Imagine typing a message on your smartphone's virtual keyboard.

Under the legacy First Input Delay (FID) metric, the browser only timed how long it took between when your finger touched the very first letter "H" and when the keyboard driver woke up. If that first letter woke up promptly in $10\text{ ms}$, the site was awarded a gold medal—even if every subsequent letter you typed took $800\text{ ms}$ to appear on the screen, causing stutter and skipped characters!

LEGACY FID (First Input Delay)
Finger Taps 'H' ──► [ Input Delay ] ──► (Stop Tracking! FID measured here)
                     [ ... The rest of the entire user session is IGNORED ... ]

MODERN INP (Interaction to Next Paint)
Finger Taps 'H' ──► [ Input Delay ] ──► [ Execute JS Callback ] ──► [ Render Next Frame ] (Total: 45ms)
Finger Taps 'E' ──► [ Input Delay ] ──► [ Execute JS Callback ] ──► [ Render Next Frame ] (Total: 38ms)
Finger Taps 'L' ──► [ Input Delay ] ──► [ Heavy Background JS ] ──► [ Render Next Frame ] (Total: 480ms ⚠️ WORST INP!)

Interaction to Next Paint (INP) represents the modern standard: It monitors every single click, tap, and keypress across the entire lifecycle of a page visit. When the user leaves the page, INP reports the single representative worst-case interaction latency.

If an interface freezes, lags, or stutters at any point during the user's journey, INP captures it.


Technical Deep Dive & Specifications

What Interactions Count Toward INP?

The Event Timing API tracks discrete user interactions requiring JavaScript event dispatch and UI rendering:

Interaction Category Eligible Events Tracked Excluded Gestures & Reasons
Mouse Clicks pointerdown, pointerup, click Continuous mousemove (hovering) is excluded to avoid telemetry flooding.
Touchscreen Taps touchstart, pointerdown, touchend Pinch-to-zoom and continuous touch panning are offloaded to the compositor thread.
Keyboard Keystrokes keydown, keyup, keypress Keystroke combinations (Ctrl+C, Alt+Tab) that trigger OS native shortcuts without browser paint.
+-------------------------------------------------------------------------------+
|                           INP INTERACTION ELIGIBILITY                         |
+-------------------------------------------------------------------------------+
|  ELIGIBLE FOR INP:                                                            |
|    ├── Mouse clicking a button, link, or custom interactive widget            |
|    ├── Tapping on a mobile touchscreen element                                |
|    └── Pressing keys inside a text input, textarea, or keyboard-navigated UI  |
|                                                                               |
|  EXCLUDED FROM INP:                                                           |
|    ├── Scrolling or swiping a long feed (handled by GPU compositor thread)    |
|    ├── Mouse hover / pointer movements across screen elements                 |
|    └── Pinching, zooming, or OS window resizing                              |
+-------------------------------------------------------------------------------+

The 3 Sub-Parts of Interaction Latency

An interaction begins the microsecond the user physically touches hardware and concludes only when the browser paints the resulting pixels to the screen. This journey is divided into three sequential sub-parts:

User Action                                                                      Display Updated
(Finger Tap)                                                                     (Pixels Rendered)
    │                                                                                   ▲
    ▼                                                                                   │
┌───────────────────────┬───────────────────────────────┬───────────────────────────────┐
│   1. INPUT DELAY      │    2. PROCESSING DURATION     │    3. PRESENTATION DELAY      │
│ (Wait on Main Thread) │ (Execute JavaScript Handlers) │ (Style + Layout + Paint + GPU)│
└───────────────────────┴───────────────────────────────┴───────────────────────────────┘

1. Input Delay ($T_{\text{input}}$)

The time between the physical user action and when the browser's main thread is actually free to begin executing the first registered event handler callback.

  • Root Cause: Long-running tasks, heavy garbage collection, or background third-party analytics running on the main thread when the user interacts.

2. Processing Duration ($T_{\text{process}}$)

The cumulative execution time spent running all synchronous JavaScript event listener callbacks associated with that interaction (pointerdown $\rightarrow$ pointerup $\rightarrow$ click).

  • Root Cause: Complex client-side algorithms, synchronous DOM queries, large array filtering, or heavy state management updates.

3. Presentation Delay ($T_{\text{present}}$)

The time between when JavaScript execution finishes and when the browser calculates style recalculation, layout reflow, rasterization, and commits the composite frame to the GPU display buffer.

  • Root Cause: Massive DOM size, recalculating styles across thousands of nodes, forced synchronous layouts, or complex CSS filter repaints.

$$\text{Total Interaction Latency} = T_{\text{input}} + T_{\text{process}} + T_{\text{present}}$$


The Session-Level INP Calculation Algorithm

How does the browser pick a single INP number for a session with hundreds of clicks?

  1. Low-Interaction Sessions ($< 50$ interactions): $$\text{Session INP} = \max(\text{All Interaction Latencies})$$ The absolute highest latency observed during the visit is the INP.

  2. High-Interaction Sessions ($\ge 50$ interactions): To prevent unusual, single-frame OS hardware hiccups from skewing telemetry, the algorithm discards 1 outlier per every 50 interactions. $$\text{INP Value} = 98\text{th Percentile of Interactions}$$

    • For example, if a user performs $100$ interactions, the worst $1$ is ignored, and the $2\text{nd}$ worst interaction becomes the reported INP.
Total Interactions: 100
[ 12ms, 15ms, 18ms, ... 180ms, 195ms ]  [ 210ms (98th % - INP) ]  [ 950ms (Discarded Outlier) ]
                                                    ▲
                                                    │
                                           REPORTED SESSION INP

💻 Interactive Code Playground

Starter Code

Line-by-Line Code Breakdown

  • Lines 55–60 (slow-btn handler): Uses a synchronous while loop to hold the main thread hostage for $250\text{ ms}$, creating an immediate $250\text{ ms}+$ Processing Duration bottleneck.
  • Lines 63–87 (PerformanceObserver): Observes entries of type 'event'.
  • Line 66 (if (!entry.interactionId) continue;): Filters specifically for interactions assigned an interactionId by the Chromium engine (distinguishing key/pointer events from passive lifecycle events).
  • Lines 68–71 (Sub-part arithmetic):
    • inputDelay = entry.processingStart - entry.startTime
    • processingTime = entry.processingEnd - entry.processingStart
    • presentationDelay = entry.startTime + entry.duration - entry.processingEnd
  • Line 87 (durationThreshold: 16): Captures all interactions exceeding $16\text{ ms}$ (one display refresh frame).

Expected Browser Render Output


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL playground.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...
[Interaction Captured: pointerdown]
• Target Node: <BUTTON> (ID: #slow-btn)
• Total Duration: 268.4 ms (FAIL >200ms)
  ├── 1. Input Delay: 2.1 ms
  ├── 2. Processing Time: 251.2 ms
  └── 3. Presentation Delay: 15.1 ms

🏋️ Hands-On Exercise

🎯 The Challenge: Diagnose and Triage INP Sub-Part Bottlenecks

Instructions:

  1. Review the performance audit data for three different failing user interactions:
    • Interaction A (Mobile Menu Toggle): Total: $380\text{ ms}$ (Input Delay: $310\text{ ms}$, Processing: $20\text{ ms}$, Presentation: $50\text{ ms}$)
    • Interaction B (Filter Dropdown Change): Total: $420\text{ ms}$ (Input Delay: $10\text{ ms}$, Processing: $380\text{ ms}$, Presentation: $30\text{ ms}$)
    • Interaction C (Accordion Expand): Total: $310\text{ ms}$ (Input Delay: $15\text{ ms}$, Processing: $25\text{ ms}$, Presentation: $270\text{ ms}$)
  2. For each interaction, identify the exact sub-part that is bottlenecking the interaction and specify the architectural engineering remedy.
  3. Write a JavaScript helper analyzeInteraction(entry) that automatically flags which sub-part exceeded its target budget ($T_{\text{input}} > 50\text{ ms}$, $T_{\text{process}} > 50\text{ ms}$, $T_{\text{present}} > 50\text{ ms}$).

🏁 Starter Code Sandbox

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
STARTER CODE SANDBOX exercise.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...

⚠️ Common Pitfalls

  1. Testing Only Mouse Clicks and Ignoring Keypresses: INP tracks keyboard events inside forms. A complex autocomplete search box that parses arrays on every keydown without yielding will fail INP even if all buttons are lightning fast.
  2. Assuming setTimeout(fn, 0) Breaks Up Processing Time: Calling setTimeout(fn, 0) queues a macro-task, but if you do not yield to the renderer before mutating the DOM, the presentation delay will still absorb the cost.
  3. Overlooking Third-Party Tag Manager Scripts: Heavy third-party advertising, analytics, and chat widget scripts running continuous loops inflate Input Delay for unrelated native UI buttons.

💡 Pro Tips

  1. Leverage the interactionId in Performance Logs: Chromium assigns a unique integer interactionId grouping together related events (such as pointerdown, pointerup, and click) from a single user physical gesture.
  2. Target Sub-50ms Budgets per Sub-Part: To comfortably pass the $\le 200\text{ ms}$ threshold in the 75th percentile of real-world low-end mobile devices, design each sub-part ($T_{\text{input}}$, $T_{\text{process}}$, $T_{\text{present}}$) to take under $50\text{ ms}$.

📌 Key Takeaways

  • INP measures the full responsiveness lifecycle ($\le 200\text{ ms}$) across all clicks, taps, and keystrokes throughout the entire page visit.
  • Unlike FID (which only measured initial input delay), INP spans Input Delay + Processing Duration + Presentation Delay.
  • Session INP reports the worst-case interaction for sessions with $<50$ events, or the 98th percentile for sessions with $\ge 50$ events.
  • Continuous gestures like scrolling and mouse movements are handled on the compositor thread and excluded from INP.
  • Resolving INP requires pinpointing which specific sub-part is responsible for the latency spike.
  • --
⭐ LEARN: HTML 🌟 ⚔️ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

What is the fundamental difference between First Input Delay (FID) and Interaction to Next Paint (INP)?

Question 1 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 2 / 3

An interaction takes 350ms total: 10ms Input Delay, 20ms Processing Time, and 320ms Presentation Delay. What is the most likely root cause?

Question 2 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 3 / 3

For a user who performs 120 distinct interactions during a checkout session, how does Chrome calculate the session-level INP?

Question 3 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP