Interaction to Next Paint became an official Core Web Vitals metric in March 2024, replacing First Input Delay. If you have not revisited your responsiveness optimization since then, your site may be scoring against a metric that has fundamentally changed. INP is harder to fix than FID, and understanding the difference between the two matters before you start making changes to your JavaScript stack.

INP vs. FID: Why the Change Matters

FID measured only the delay before the browser started processing the first user interaction — it excluded the time the event handler took to run and the time to paint the result. A site could have excellent FID and still feel sluggish because the handler itself took 400ms to execute and the next paint took another 200ms. INP closes that gap. It measures the full cycle: from the moment the user interacts (click, keypress, tap) to the moment the browser presents the next frame. This is the true responsiveness number — the one that matches what users actually experience.

Good INP is under 200ms. Needs Improvement is 200–500ms. Poor is above 500ms. Google uses the 98th percentile of all interactions from real users — meaning your worst interactions, not your average, determine the score. A page that responds instantly to most clicks but has one interaction that takes 700ms will score in the Poor range.

What Causes Poor INP

Almost always: too much work on the main thread during or immediately after an interaction. JavaScript is single-threaded. When the main thread is busy — running a large script, parsing a network response, executing a heavy event handler — any interaction during that window has to wait for the current task to finish before it can be processed. The user clicks and nothing happens for 600ms. That is a Poor INP interaction, and if it happens to enough real users, it tanks the field score.

Common sources of main-thread congestion:

  • Third-party scripts (ad networks, analytics, tag managers, chat) executing synchronously on page load
  • Large JavaScript bundles that take significant time to parse and compile
  • Heavy React or Vue component re-renders triggered by state changes on interaction
  • Synchronous localStorage or cookie reads inside event handlers
  • DOM manipulation that forces a full style recalculation and layout pass before painting
  • Long-running event listeners that do more processing than necessary before allowing the browser to paint

How to Diagnose INP Problems

Start with Chrome DevTools. Open the Performance panel and enable the Interaction recorder (available in Chrome 114+). Record while interacting with the page — click navigation items, open menus, type in search boxes, submit forms. Look for Long Tasks shown in red on the Main thread row. Click on a task to see the call stack. The bottom panel identifies the specific function and file responsible for the blocking work. This pinpoints exactly what to fix rather than guessing.

For field data, deploy the web-vitals JavaScript library with interaction attribution. It logs the element, event type, and timing breakdown for every interaction and reports the 98th-percentile INP. Send this data to your analytics platform. Without field-level attribution, you are essentially guessing at what your real users are experiencing — synthetic tools miss the specific interaction patterns that create real-world INP problems.

Breaking Up Long Tasks

The core fix for INP is preventing long tasks from blocking the main thread. Any task that runs for more than 50ms is a Long Task and a potential INP contributor. The modern approach is scheduler.yield(), which pauses execution and yields back to the browser between chunks of work, allowing input events to be processed. Where that API is not available, setTimeout(fn, 0) achieves a similar result by deferring the next chunk to the next task queue tick.

For React applications, heavy re-renders are frequently the culprit. React.memo, useMemo, and useCallback prevent unnecessary re-renders when props have not changed. React 18 Concurrent Mode and the startTransition API let you mark non-urgent state updates so they do not block input processing — the UI stays responsive while heavy rendering work happens in the background.

Third-Party Script Audit

I have seen sites with INP scores over 800ms where deferring two third-party scripts was the entire fix. Ad networks in particular inject synchronous code that runs as soon as the script downloads, often before the DOM is interactive. Use the defer or async attribute on script tags where possible. For scripts loaded through Google Tag Manager, set trigger timing to DOM Ready or Window Loaded instead of Page View — this delays their execution until after the initial interactive state is established. Remove scripts that are no longer actively used. I routinely find dead analytics tags, old A/B testing libraries, and retired heatmap scripts still loading on every page, consuming main-thread time for zero business value.

Input Handler Efficiency

Keep event handlers lean. An effective handler does the minimum work to update state, defers any heavy rendering work using requestAnimationFrame or scheduler.yield(), and avoids forced synchronous layout. Forced synchronous layout — reading a layout property like offsetHeight immediately after writing to the DOM in the same handler — forces the browser to recalculate layout before the read can complete. This happens synchronously on the main thread and is a reliable INP contributor. Batch DOM reads separately from DOM writes to avoid this pattern.

Measuring Progress Accurately

Because INP is measured in field data at the 98th percentile, lab tools miss it reliably. Lighthouse and PageSpeed Insights will show you TBT (Total Blocking Time) as a proxy, but it does not map directly to INP. Deploy the web-vitals library with logging, run it for two to four weeks, and track both the 98th-percentile INP value and the specific interactions driving it. This is the only way to confirm that your fixes are reaching real users rather than just improving synthetic scores.

INP fits into a broader performance strategy alongside LCP and CLS. For a practitioner-level walkthrough of how to sequence fixes across all three, see Core Web Vitals optimization. If page weight and script loading are the root cause in your case, page speed optimization covers the delivery stack in more depth. A website audit will identify whether INP is your primary concern or whether crawl and indexation issues should take priority first.