What INP measures
Interaction to Next Paint is the time, in milliseconds, between a user interaction and the next visible update to the screen. Interactions that count: taps on mobile, mouse clicks on desktop, and key presses inside form fields. Interactions that do not count: scrolling, hovering, gestures that do not trigger an event handler. See the Core Web Vitals explained chapter for the wider metric context.
The threshold to pass is 200ms or less. Between 200 and 500ms is Needs Improvement. Over 500ms is Poor. The number reported is the 75th percentile of real-user field data, with INP itself taking the single worst interaction for short sessions (under 50 interactions) or the 98th percentile for long ones. Either way, the reported value is the bad-day case, not the average.
The reason INP matters more than the legacy responsiveness metric is that a single 1.2-second hang on a click handler is exactly the kind of moment that makes a site feel broken. The user taps Add to Cart, nothing happens for over a second, they tap again, then a queue of three add-to-cart actions all fire at once. INP captures that experience honestly in a way that page-load metrics never did.
Why FID was retired
First Input Delay had two design flaws that made it easy to game.
It only measured the first interaction. A page that locked up on every interaction after the first one still passed FID, because the metric stopped measuring after the first tap. Sites with heavy carousel scripts, image galleries, or single-page-app hydration could all pass FID while feeling terrible to use.
It only measured input delay, not response. FID was the time between the user input and the moment the browser started running the event handler. It did not measure how long the handler ran, and it did not measure how long until the screen updated. A handler that took 3 seconds to run after a 30ms input delay scored an excellent FID of 30ms and was still a disaster to use.
Google announced INP as an experimental metric in 2022, gave the web a 22-month transition window, then promoted INP to a stable Core Web Vital on 12 March 2024. FID stopped being measured by CrUX in September 2024. Sites that had never built for responsiveness saw their CWV pass rate fall sharply during the transition. Most of the sites we audited in 2024 needed real JavaScript work to recover.
How INP is calculated
Every interaction on the page is timed in three sub-components.
- Input delay. The time from the user action to the browser starting to run the event handler. Caused by the main thread being busy with other work when the interaction lands.
- Processing time. The time the event handler actually runs. Caused by the work inside your click handler (DOM updates, framework reconciliation, network requests, expensive calculations).
- Presentation delay. The time from the handler finishing to the next visible paint. Caused by render-blocking work that happens after the handler (layout, paint, composite).
The sum of the three is the latency for that interaction. The longest such interaction in the session is the page INP. Chrome records this for every visit and rolls it into CrUX as the 75th percentile across all users over the 28-day window.
The practical effect is that you have three places to look when diagnosing a slow INP, and you have to look at all three. Fixing the handler when the bottleneck is input delay does nothing. Fixing the input delay when the bottleneck is presentation delay does nothing.
The common causes of poor INP
From the sites we audit, four patterns account for the majority of failing INP scores.
Heavy third-party tags. Google Tag Manager firing 30 separate tags, a chat widget loading 600KB of JavaScript synchronously, a marketing pixel running a recursive script on every page change. Any of these can lock up the main thread for hundreds of milliseconds at the wrong moment. Most Perth e-commerce sites we see ship with at least one of these problems.
Single-page-app hydration. React, Vue, Nuxt and Next sites that hydrate the entire DOM on first load freeze input handling until hydration completes. The user can see the page, but tapping anything does nothing for a second or two. Modern frameworks (React Server Components, Astro islands, partial hydration) exist specifically to fix this.
Long-running click handlers. A click handler that does too much synchronous work: DOM lookups, network requests, image processing, route changes that re-render half the page. The fix is to break the work into smaller chunks, defer the non-critical parts, or move heavy computation to a Web Worker.
Layout thrashing. An event handler that reads layout properties (offsetHeight, getBoundingClientRect) and then writes to the DOM, then reads again, in a loop. Each read forces a synchronous layout recalculation. A 12-item loop with read-then-write can spend 400ms in layout alone.
Diagnosing a failing INP
The workflow we run on every client INP investigation:
- Confirm field data is failing. Open the GSC Core Web Vitals report. Note which URL group is failing INP, on mobile or desktop. Pull two or three representative URLs.
- Reproduce in DevTools. Open the page in Chrome with mobile emulation, 4x CPU throttling, and Slow 4G network throttling. Open the Performance panel and start a recording.
- Interact like a user. Click the most common interaction targets: hamburger menu, search box, Add to Cart, Read More, accordion toggles, form fields. Each interaction should fire an event the trace will capture.
- Identify the slow interaction. The Interactions track in the Performance panel highlights interactions that took over 200ms. Click on the worst one. The flame graph shows exactly which script function consumed the time.
- Trace to a specific function. The bottom-up view aggregates the time spent in each function. The top one is almost always your slow handler. Sometimes it is a third-party script you did not write.
The Web Vitals Chrome extension is also worth installing. It displays live INP values for every interaction on the page, which makes ad-hoc testing much faster than running a full Performance trace.
The fix workflow
Once you have identified the slow handler, the fix follows one of these patterns.
Break long tasks into smaller chunks. A task that runs for 200ms blocks the main thread for 200ms. Splitting the same work into ten 20ms tasks with yields between them lets the browser process input between chunks. The scheduler.yield() API (Chrome 129+) is the cleanest way to do this, with setTimeout(fn, 0) as the broadly supported fallback.
Defer non-critical work to idle time. Work that does not need to happen immediately can run in requestIdleCallback(). Analytics events, prefetch hints, cache warming, non-visible DOM updates: all good idle-time candidates. Reduces input delay because the main thread is more often free when interactions arrive.
Move heavy computation to a Web Worker. Image processing, large data transformations, JSON parsing of 1MB payloads, anything CPU-intensive. Workers run on a separate thread and do not block input handling. The cost is some plumbing to pass data across the worker boundary, but for genuinely heavy work it is the only solution that fully fixes INP.
Defer or remove heavy third-party tags. Audit Tag Manager. Anything that does not need to run before first paint should be delayed. Anything that does not contribute meaningfully to revenue or measurement should be removed. Many sites ship with abandoned tags from old campaigns still firing on every page. The JavaScript SEO chapter covers the wider JS pruning workflow.
Fix layout thrashing. Read all DOM properties first, write all DOM updates second. Never mix reads and writes inside a loop. Libraries like FastDOM enforce this batching automatically. For React and Vue codebases, profile the slow component and look for forced reflows in render.
Show immediate feedback. If a click does something genuinely slow that cannot be made faster (a server round trip, a heavy state update), show a loading state on the first frame after the click. The visible response is what the user perceives. A 600ms operation that paints a spinner at 16ms feels fast. The same 600ms operation with no visible feedback feels broken.
Do
- Throttle CPU to 4x and network to Slow 4G when testing
- Use the Web Vitals extension for live INP readings
- Break long tasks with
scheduler.yield()orsetTimeout - Show a loading state on the first frame after slow clicks
- Audit Tag Manager every quarter and remove dead tags
Don't
- Test only on a fast desktop with broadband
- Trust FID numbers (the metric is dead)
- Mix DOM reads and writes inside a loop
- Run heavy analytics synchronously in the document head
- Ship a fix and check Search Console the next day
Common mistakes
Optimising for desktop and forgetting mobile. CrUX weights mobile separately and most failing INP scores fail on mobile only. The Pixel 5 is roughly the slowest device Google publishes as a reference benchmark for mid-range hardware, and many real users in Perth are on devices considerably slower than that. Always test with mobile CPU throttling.
Confusing INP with Total Blocking Time. TBT is a lab metric in Lighthouse that approximates INP, but they do not move in lockstep. A page can have a TBT of 200ms (good) and still have an INP of 800ms (poor) because the slow interaction is not on initial load. The Lighthouse chapter covers the difference.
Removing all third-party scripts indiscriminately. Some third-party scripts are revenue-critical (the Stripe checkout, the booking widget, the chat tool the sales team depends on). The goal is to defer or load them late, not to delete them. Audit, measure, decide per-script.
Treating CWV as a tiebreaker boost. It is not. The signal is small and confirmed but small. Pass the threshold, then move on to the content and link work that actually moves rankings. See the pillar guide for the honest framing.
Tools and checklist
Free tools for the full INP workflow:
- PageSpeed Insights. Field-data INP for the URL, plus a Lighthouse lab run with TBT and interaction diagnostics.
- Chrome DevTools Performance panel. The Interactions track and the flame graph identify the specific slow handler.
- Web Vitals Chrome extension. Live INP readings as you click around the page. The fastest feedback loop available.
- Lighthouse. The Performance audit reports TBT, which approximates INP for the initial-load phase.
- GSC Core Web Vitals report. The official field-data view. Slow to update but it is what Google uses for ranking.
Pre-launch checklist:
- All Tag Manager tags audited and unused tags removed
- Critical third-party scripts deferred or loaded async
- Long-running event handlers profiled and chunked
- Heavy computation moved to a Web Worker
- Layout reads and writes batched (no read-write-read inside loops)
- Loading states added to any click that takes more than 100ms
- Mobile testing done with 4x CPU + Slow 4G throttling
- Field data tracked in GSC for 28 days post-fix
Perth and WA context
Two INP patterns specific to Perth and WA businesses.
Tag-heavy e-commerce sites are the worst offenders. A Perth e-commerce site running Shopify with twelve apps installed, Tag Manager firing twenty tags, a live chat widget, a reviews widget, and a stock-counter widget will fail INP almost by default. The fix is rarely a single quiet code change. It is a hard audit of every app, every tag, and every script, and a willingness to delete some of them. The e-commerce SEO chapter covers the wider context.
Service-business sites usually pass INP without trying. A typical Perth tradie or law firm site has light JavaScript, a contact form, maybe a Google Maps embed. INP is rarely the failing metric for these sites. Trades SEO and legal SEO sites should still test, but the fix budget should go to LCP and content work, not to INP.
For sites that have a real INP problem, the speed optimisation service is the engagement. New properties should start with a free SEO audit that flags INP issues in context. For broader Perth coverage see Perth services, Local SEO Perth, and regional pages including Fremantle SEO and Joondalup SEO. The CLS fixes chapter, LCP optimisation chapter and Lighthouse explained chapter cover the other Vitals work that usually accompanies an INP fix.