A bad INP score is usually diagnosed as "too much JavaScript on the main thread," which is true but incomplete. Hosting and rendering strategy decide how much JavaScript your architecture needs in the first place — a slow origin or a hydration-heavy setup manufactures the exact main-thread load that then gets blamed on the code alone.

Key takeaways

  • Google's threshold: under 200ms is good, 200-500ms needs improvement, above 500ms is poor.
  • JavaScript trimming treats the symptom. Architecture decisions upstream decide how much JavaScript exists to trim.
  • Hydration is the specific mechanism connecting rendering strategy to INP — not "JavaScript" in the abstract.
  • Third-party scripts are usually the biggest single main-thread cost, and they're neither your hosting nor your rendering choice, but they compound both.
  • Fixing INP properly means fixing it in the right order: architecture, then hydration cost, then per-interaction code — not the reverse.

What counts as a bad INP score

Google's Interaction to Next Paint threshold is under 200 milliseconds for "good," 200 to 500 milliseconds for "needs improvement," and above 500 milliseconds for "poor." INP replaced First Input Delay as an official Core Web Vital in March 2024, and unlike FID it measures the full interaction — input delay, processing time and rendering — not just the initial lag.

That broader measurement is exactly why INP is harder to fix with the usual front-end checklist. FID mostly punished one bad first click. INP punishes every slow interaction across a session — every dropdown, every filter, every form field — which means the causes are more distributed, and "reduce your JavaScript bundle" stops being sufficient advice on its own.

Hydration
The process of attaching JavaScript event handlers to server-rendered HTML so it becomes interactive. Until hydration completes, clicks either do nothing or get queued behind it. On a JavaScript-heavy page, hydration itself can occupy the main thread long enough to directly worsen the very first interactions a visitor attempts — before any of the site's actual feature code has run at all.

The chain most INP advice skips

Server response time and rendering strategy decide how much client-side work has to happen before a page is interactive. A slow origin pushes teams toward heavier client-side rendering to mask the delay with a loading skeleton, and heavier client-side rendering means more hydration cost — which is the JavaScript INP guides tell you to trim, arriving after the architecture already decided how much of it would exist.

How upstream architecture decisions become the JavaScript that INP guides tell you to fix.
Upstream decision Downstream effect What generic advice targets
Slow origin / high TTFB Pressure to render more client-side to mask load delay "Reduce your bundle size"
Client-side-only rendering Full hydration required before any interaction works "Defer non-critical JavaScript"
Heavy component libraries Larger hydration payload, longer main-thread occupation "Code-split your routes"
Third-party scripts (chat, ads, analytics) Compete with your own code for the same main thread "Load third-party scripts lazily"

None of the right-column advice is wrong. It's just applied to the output of decisions that were made earlier and elsewhere — often by a different person, often for reasons that had nothing to do with INP at the time. Fixing the JavaScript without revisiting the architecture is treating a symptom whose cause keeps regenerating it.

The one cause that isn't architecture: third-party scripts

Chat widgets, tracking pixels and ad scripts are consistently the largest single contributor to poor INP on sites that otherwise have reasonable architecture. They run on your main thread, on your time budget, using code you don't control and usually can't optimise — only load conditionally or remove.

This is the exception to the "it's upstream architecture" argument above: third-party scripts are neither a hosting decision nor a rendering-strategy decision, and they can wreck INP on a server-rendered, minimally-hydrated page just as effectively as on a heavy client-side app. Audit them separately from the architecture question — they're usually the fastest real win available.

Fixing it in the right order

  1. Check server response time first. If TTFB is high, start at the hosting guide — no front-end fix outruns a slow origin.
  2. Check rendering strategy second. Confirm content and initial interactivity don't depend on a large client-side hydration pass. The rendering-strategy table in the SEO pillar covers the same trade-off from the crawlability side.
  3. Audit third-party scripts third. Defer anything not needed for the first interaction; remove anything not earning its cost.
  4. Then, and only then, profile your own code. Break up long tasks, debounce expensive handlers, move genuinely heavy work off the main thread. This is where generic INP advice starts — correctly, just too late in the sequence to be the whole fix.
Why this order matters. Doing step four first commonly buys a real but small improvement, then the next redesign or feature addition reintroduces the same INP problem — because the architecture that manufactures heavy client-side work was never addressed. Fixing the JavaScript without fixing the architecture is a recurring cost, not a one-time fix.

The short version

A bad INP score has a JavaScript-shaped symptom and, very often, an infrastructure-shaped cause. Trimming code helps and is worth doing regardless — but check server response time and rendering strategy first, because those decide how much code there was to trim in the first place.

Badri Dutta

Software engineer · 15 years building for the web

Fifteen years building for the web and eight doing technical SEO, which is why this piece treats a Core Web Vitals problem as a full-stack question rather than stopping at the browser tab.

Full background →