INP optimization is a field-to-trace workflow: identify the slow real-user cohort, capture enough attribution to name the interaction without collecting sensitive content, reproduce that interaction in DevTools, fix its dominant latency phase, and validate the release in the same cohort. A load-only lab score cannot tell you which post-load interaction real visitors found slow.
This guide turns that workflow into an INP Evidence Packet. It connects a field cohort, a privacy-minimized attribution schema, a repeatable trace, a phase-to-fix matrix, and a release ledger. Download the INP Evidence Packet (Markdown) to use the complete worksheet. The packet is a diagnostic method, not a benchmark, traffic forecast, ranking promise, or guarantee of a commercial outcome.
What does INP actually measure?
Interaction to Next Paint measures the latency of qualifying click, tap, and keyboard interactions during a page visit. The interval starts when the input is received and ends when the browser presents the next frame. Hover and scrolling are not included in the metric.
INP normally represents the page's worst interaction. On pages with many interactions, the calculation allows one high-latency outlier to be ignored for every 50 interactions. A page without a qualifying interaction has no INP value for that visit. These details matter: an average over every event is not INP, and a synthetic page load without an interaction has not measured it.
For Core Web Vitals assessment, evaluate the 75th percentile separately for mobile and desktop visits:
| INP at the 75th percentile | Classification |
|---|---|
| 200 ms or less | Good |
| More than 200 ms and up to 500 ms | Needs improvement |
| More than 500 ms | Poor |
The latency of one interaction can be split into three parts:
INP candidate = input delay + processing duration + presentation delay- Input delay is the wait before event callbacks begin. Main-thread work already in progress is a common cause.
- Processing duration is the time spent running the interaction's event callbacks.
- Presentation delay is the wait from the end of the callbacks until the browser presents the next frame.
The equation is a diagnostic decomposition, not a rule that all three parts deserve equal effort. Fix the largest attributable phase first, then trace again because removing one bottleneck can expose another.
For the broader relationship between responsiveness, loading, and visual stability, use the Core Web Vitals field-to-fix guide. This page stays deliberately narrower: it owns the slow-interaction investigation from field signal to release evidence.
Start with a field cohort, not a page score
Field and lab tools answer different questions. Combining them is useful; substituting one for another is not.
| Evidence source | Question it can answer | Important limitation |
|---|---|---|
| Search Console Core Web Vitals | Which Google-defined URL groups have a field CWV issue? | It groups URLs and does not identify the slow interaction or source code |
| CrUX | What is the aggregate real-user distribution for an eligible URL or origin? | Public, aggregated data can be sparse and cannot explain the cause |
| First-party RUM | Which route, release, device class, component, and interaction phase are slow? | Only as trustworthy as its coverage, privacy design, sampling, and release labels |
| DevTools trace | What occupied the main thread and rendering pipeline during a reproduced interaction? | One controlled trace is not the population distribution |
| Lighthouse TBT | Is load-time main-thread work likely to delay input? | TBT is a lab proxy for load-time blocking, not a measurement of post-load INP |
Begin with the narrowest cohort your data can support without making it too small to interpret. A practical cohort record may include:
- stable route template, not a full URL with query parameters;
- mobile or desktop device class;
- browser major version when support volume justifies it;
- coarse market or deployment region;
- release identifier;
- interaction type and approved component label;
- sample count, collection period, sampling rate, and missing-data rate;
- INP distribution plus the input-delay, processing, and presentation distributions.
Do not compare a mobile checkout cohort from one release with a desktop marketing-page cohort from another and call the difference an improvement. Keep the segmentation stable across baseline, reproduction, rollout, and validation.
CrUX and Search Console are strong discovery signals, but they do not replace first-party attribution. CrUX eligibility and aggregation rules can exclude low-traffic pages, group parameterized URLs in unexpected ways, and include iframe interactions in the top-level page metric even when a top-level RUM implementation cannot inspect a cross-origin frame. Record those limitations before interpreting a mismatch.
Capture useful attribution without collecting user content
The web-vitals attribution build exposes the phase timings, interaction type, interaction target, load state, and related Long Animation Frame entries needed for a useful field record. The default target can be a selector-like string. A safer pattern is to approve a small set of coarse component labels and return only those labels from generateTarget.
The following sample was reviewed against web-vitals 5.3.0. Declare that package as a direct application dependency and test upgrades deliberately; do not rely on another package's transitive copy.
import { onINP } from 'web-vitals/attribution';
type INPRecord = {
metricId: string;
routeTemplate: string;
release: string;
value: number;
rating: 'good' | 'needs-improvement' | 'poor';
interactionType: 'pointer' | 'keyboard' | 'unknown';
component: string;
loadState: string;
inputDelay: number;
processingDuration: number;
presentationDelay: number;
loafCount: number;
};
function approvedComponentLabel(node: Node | null): string {
if (!(node instanceof Element)) return 'unclassified';
return (
node.closest<HTMLElement>('[data-rum-component]')?.dataset.rumComponent ??
'unclassified'
);
}
function sendINP(record: INPRecord): void {
const body = new Blob([JSON.stringify(record)], {
type: 'application/json',
});
navigator.sendBeacon('/rum/web-vitals', body);
}
onINP(
(metric) => {
const { attribution } = metric;
sendINP({
metricId: metric.id,
routeTemplate:
document.documentElement.dataset.routeTemplate ?? 'unclassified',
release: document.documentElement.dataset.release ?? 'unclassified',
value: Math.round(metric.value),
rating: metric.rating,
interactionType: attribution.interactionType ?? 'unknown',
component: attribution.interactionTarget || 'unclassified',
loadState: attribution.loadState ?? 'unknown',
inputDelay: Math.round(attribution.inputDelay),
processingDuration: Math.round(attribution.processingDuration),
presentationDelay: Math.round(attribution.presentationDelay),
loafCount: attribution.longAnimationFrameEntries?.length ?? 0,
});
},
{
reportAllChanges: true,
generateTarget: approvedComponentLabel,
},
);Add data-route-template and data-release from trusted application configuration, and add data-rum-component only to approved interaction surfaces such as product-filter, nav-drawer, or checkout-submit. Do not derive labels from user-entered text, account identifiers, product names, query strings, or arbitrary DOM content.
With reportAllChanges: true, the callback can report updated candidates during a page visit. Store the latest record for a metric ID or model the updates explicitly; do not sum repeated callbacks as separate interactions. Define delivery failure and sampling behavior as well. sendBeacon() returning false, an ad blocker, page termination, or consent policy can create missing data.
Long Animation Frame attribution can help connect a slow interaction to script work, but browser support is not universal and the API remains experimental. Use coarse script categories only when your privacy policy permits them. The example sends a count rather than source URLs, stack text, or raw event data.
Reproduce the same interaction in Chrome DevTools
A useful trace is a controlled attempt to reproduce the affected field cohort, not a random click on a fast development machine.
- Write the field hypothesis. Name the route template, device class, release, component label, interaction type, dominant phase, and field percentile you are trying to explain.
- Match the deployed build. Prefer a production-like environment with the same code splitting, feature flags, consent state, data volume, and third-party scripts. Never debug a minified production session with personal customer data exposed.
- Match the interaction state. Open the same menu, filter, editor, cart, or validation state that precedes the slow action. Warm and cold application states may behave differently, so record which one you test.
- Set realistic constraints. In DevTools, use CPU and network throttling as controlled variables rather than claims that one preset represents every real device. Record the chosen settings.
- Record the action. Start a Performance trace, perform the attributed interaction once, wait for the visual update, and stop recording. Capture multiple traces rather than selecting the fastest run.
- Find the interaction. Inspect the Interactions track or INP insight and expand the input-delay, processing, and presentation phases. Confirm that the target and action match the field hypothesis.
- Inspect the dominant phase. Use the Main thread, Bottom-up, Call tree, Event log, rendering events, and third-party annotations to locate work inside or immediately before the interaction.
- Change one causal mechanism. Apply the smallest testable fix, repeat the same interaction under the same conditions, and retain before-and-after traces with the release candidate.
If the interaction cannot be reproduced, do not optimize the nearest long task by intuition. Improve field attribution, reproduce the data volume or application state, or test a representative lower-end device. A trace for a different action is evidence about that action only.
Diagnose the dominant INP phase
High input delay: the handler is waiting to start
Input delay grows when the main thread is occupied as the user interacts. Common mechanisms include a long task from startup code, hydration, a third-party script, a timer, a large state update, or earlier application work.
Inspect the trace immediately before the event callback. Identify the task, its initiating script, and whether it was essential at that moment. Possible fixes include:
- split or defer non-critical startup work;
- schedule background work when it cannot block likely interactions;
- break long tasks and yield between independent units of work;
- remove duplicate initialization or repeated parsing;
- load third-party code by consent and need, then verify its runtime cost;
- reduce hydration or client boot work on routes that do not need it.
Yielding is not a license to fragment one atomic update into inconsistent visual states. Preserve correctness and accessibility while moving genuinely independent work out of the critical interval.
High processing duration: the handler itself is expensive
Processing duration points to the callbacks associated with the interaction. Inspect JavaScript samples, event handlers, framework work, and synchronous APIs within the interaction interval.
Typical fixes include:
- reduce the data scanned or transformed by the handler;
- avoid serial work that can be calculated once, cached, or moved off the critical path;
- update only the state and components affected by the action;
- debounce input-driven work only when delayed execution matches the interaction contract;
- move suitable CPU-heavy calculation to a worker, accounting for serialization cost;
- provide immediate, truthful visual feedback before continuing non-critical work.
Do not use a worker or a transition merely because it sounds modern. The trace must show that the moved or deferred work owned meaningful processing time, and the new behavior must remain correct for keyboard, pointer, and assistive-technology users.
High presentation delay: the update is waiting to render
Presentation delay begins after event callbacks end and lasts until the next frame is presented. It can grow because the browser must recalculate styles, lay out a large or invalidated subtree, paint expensive content, or wait behind additional main-thread work before rendering.
Inspect style recalculation, layout, paint, rendering opportunities, DOM size, and forced synchronous layout. Potential fixes include:
- batch DOM reads before writes instead of alternating between them;
- avoid reading layout immediately after invalidating styles;
- reduce the rendered or invalidated subtree;
- virtualize long interactive lists only when focus, semantics, and findability remain usable;
- use CSS containment where the containment boundary is valid;
- simplify expensive visual effects on the affected state;
- keep immediate feedback small and cheap to render.
A fast handler followed by a broad framework commit can still have high presentation delay. Stop the trace at the next presented frame, not at the end of the callback.
Use a phase-to-fix decision matrix
The matrix below is a triage tool. It does not replace a trace or authorize a fix by itself.
| Dominant evidence | Confirm in the trace | First intervention to test | Regression guardrail |
|---|---|---|---|
| Input delay before an early interaction | Startup or hydration task overlaps the input | Split, defer, or remove non-critical boot work | No broken initialization, analytics, or consent behavior |
| Input delay from recurring application work | Timer, subscription, observer, or third-party task occupies the main thread | Reduce frequency, scope, or synchronous work | Background function still completes when required |
| Processing in one handler | Long call tree inside the event callback | Reduce algorithmic work or move independent work after feedback | Result remains correct and repeat actions stay consistent |
| Processing across many components | Broad state update or framework render | Narrow state ownership and render scope | State does not become stale or divergent |
| Presentation delay with forced layout | Layout read follows style or DOM writes | Separate reads and writes; remove layout thrashing | Visual geometry and focus placement remain correct |
| Presentation delay on a large subtree | Wide style, layout, or paint invalidation | Reduce DOM/render scope or apply valid containment | Content remains accessible, searchable, and printable as required |
| Slow cross-origin embedded interaction | Field metric implicates page, but top-level RUM lacks target detail | Profile the embed with vendor cooperation or an isolated test | Parent-page messaging, consent, and fallback remain correct |
| Slow field cohort not reproducible in lab | No matching trace under recorded conditions | Improve attribution and reproduce device/data/state before editing | Do not ship an unrelated speculative optimization |
Retest after each material change. An interaction can move from processing-bound to presentation-bound once the handler becomes faster.
Account for frameworks, hydration, and third parties
Framework choice alone does not determine INP. A small React interface can respond quickly; a framework-free page can still block the main thread with expensive event code. Diagnose the executed work and render scope.
For hydrated applications, ask four trace-level questions:
- Did hydration or startup work delay the event callback?
- Did the interaction update more state or components than required?
- Did the commit invalidate a larger layout or paint area than required?
- Did a third-party task overlap the input or next rendering opportunity?
Possible architecture changes include partial hydration, server-rendered routes with limited client ownership, smaller islands of interactivity, route-level code reduction, or a different state boundary. Those are larger decisions than an event-handler fix. Use the headless React architecture guide to frame that trade-off, and involve performance evidence before turning one slow interaction into a rewrite proposal.
For third-party code, separate transfer cost from runtime cost. A script can be cached yet still execute at the wrong time. Record the provider, purpose, consent state, initiating task, and interaction overlap. Then test delayed initialization, reduced configuration, an alternative integration, or removal. Keep product and legal owners in the decision when the script serves a required function.
Validate the release in layers
Do not wait for one dashboard number and then declare success. Use three time horizons.
1. Pre-release trace validation
Repeat the same action and conditions across several traces. Confirm that the intended phase shrank and that the work was removed, reduced, or moved—not hidden by a different state. Check keyboard behavior, focus, announcements, validation, visual correctness, error paths, and repeated interactions.
2. Early release RUM validation
Roll out with a release label and compare equivalent field cohorts. Monitor:
- sample volume and telemetry completeness;
- INP and all three phase distributions;
- the affected component and interaction type;
- errors, aborted actions, and duplicate submissions;
- nearby Core Web Vitals and route-level performance;
- product guardrails defined by the interaction owner.
Use a staged rollout when the code path or audience is high risk. Set keep, revise, and rollback criteria before examining the result. A median improvement does not excuse a worse 75th or 95th percentile for the affected cohort.
3. Mature aggregate field validation
Use CrUX and Search Console after their reporting windows have incorporated enough post-release traffic. Confirm that the affected URL group or origin distribution moves in the expected direction. Do not attribute an aggregate change to the release if traffic mix, URLs, browser versions, experiments, or other deployments changed at the same time.
Core Web Vitals are one part of Google's page-experience systems, not a guarantee of ranking movement. Keep technical performance, crawl/index behavior, search visibility, conversions, and revenue as separate outcomes. For the search-quality and implementation context, see technical SEO for AI-driven search.
Build an INP Evidence Packet
Keep the investigation auditable in one small packet rather than scattering screenshots and dashboard links across a chat thread.
A. Field cohort record
Record the route template, device class, market, release, interaction type, component label, collection period, sampling rule, sample count, missing-data notes, and baseline distributions. Link the relevant Search Console or CrUX group without treating it as root-cause evidence.
B. Privacy and telemetry record
List every collected field, its purpose, retention, access owner, consent basis where applicable, redaction rule, and fallback value. Verify that route parameters, raw selectors, input text, account identifiers, and unrestricted script URLs are absent.
C. Trace record
Record the build, data state, feature flags, device, browser, throttling, interaction steps, trace filename, dominant phase, responsible work, and reproduction rate. Keep both baseline and candidate traces.
D. Phase-to-fix hypothesis
State the observed mechanism, proposed intervention, expected phase, correctness risk, accessibility risk, and falsification condition. “Improve INP” is not a hypothesis; “move the non-critical product-index refresh out of the filter callback to reduce processing duration without delaying selected-filter feedback” is testable.
E. Release ledger
Record rollout dates, exposure, release IDs, guardrails, incidents, pre-release trace result, early RUM result, mature aggregate result, and the keep/revise/rollback decision. Include limitations and unresolved cohorts.
Working artifact: Download the INP Evidence Packet (Markdown) to record the field cohort, privacy decisions, reproduction trace, phase-specific hypothesis, accessibility checks, rollout, and separated technical and business outcomes.
Use this release checklist
- [ ] The field cohort is stable enough to compare before and after the release.
- [ ] The slow interaction is labelled with an approved coarse component name.
- [ ] RUM stores no user-entered text, unrestricted selectors, or personal identifiers.
- [ ] Sampling, consent, missing-data, and repeated-callback behavior are documented.
- [ ] The DevTools trace reproduces the same route, state, action, and release family.
- [ ] The dominant input, processing, or presentation phase is named.
- [ ] The code change addresses evidence in that phase.
- [ ] Keyboard, focus, assistive feedback, visual correctness, and error paths pass.
- [ ] Pre-release traces use recorded, repeatable conditions.
- [ ] The rollout has a release label, guardrails, and rollback owner.
- [ ] Early field results compare equivalent cohorts and include tail latency.
- [ ] Mature CrUX or Search Console validation is separated from immediate RUM evidence.
- [ ] Performance, search, and business outcomes are reported separately.
- [ ] Limitations and unresolved interactions remain visible.
If your team has a Core Web Vitals problem but cannot connect the field signal to a reproducible interaction, AppWebSeo's Core Web Vitals performance service can structure the cohort, trace, and release evidence. If the bottleneck belongs to hydration, rendering ownership, or client architecture, the modern headless React architecture service can evaluate a narrower architectural intervention without assuming that a rebuild is the answer.
Sources, verification date, and limitations
The factual and implementation guidance was checked on 25 September 2026 against:
- Google Search Central: Understanding Core Web Vitals and Google search results
- web.dev: Interaction to Next Paint
- web.dev: Optimize Interaction to Next Paint
- web.dev: How to find slow interactions in the field
- Chrome DevTools: Performance features reference
- Chrome DevTools: INP breakdown insight
- Chrome UX Report methodology
- GoogleChrome/web-vitals attribution API
- MDN: PerformanceLongAnimationFrameTiming
- W3C: Event Timing
Browser tooling, metric libraries, framework behavior, and reporting interfaces change. Recheck package types, browser support, DevTools labels, consent requirements, and platform documentation before implementing the sample. Field data can be biased by eligibility, consent, browser coverage, sampling, blocked telemetry, traffic mix, URL grouping, and cross-origin iframe visibility. The workflow reduces diagnostic ambiguity; it does not eliminate it.