How to fix INP when your score is poor
You fix a poor Interaction to Next Paint score by finding the specific interactions that are slow and removing or deferring the main-thread work that blocks them. INP is rarely about one slow function. It's usually a busy main thread caused by scripts that have nothing to do with what the visitor clicked.
Google's threshold for good INP is 200 milliseconds or less at the 75th percentile of real visits, and it's the Core Web Vital most sites now fail. If you're new to the three metrics, our guide to Core Web Vitals for marketers and founders explains them in business terms. This article is the practical fix list for marketing sites, where the causes are different from those in web apps.
What causes poor Interaction to Next Paint on marketing sites?
Poor INP on marketing sites comes from four sources: third-party tags, chat and support widgets, heavy animation, and large amounts of JavaScript hydrating on load. Usually two or three are present at once.
Cause | Why it hurts INP | Typical fix |
|---|---|---|
Tag manager full of tags | Each tag runs code on load and on clicks, keeping the main thread busy | Remove unused tags; delay the rest until idle |
Chat and support widgets | Large scripts that initialize on every page view | Click-to-load facade |
Scroll and hover animation | Effects that run on every scroll frame or force layout recalculation | Animate transform and opacity; trim scroll effects |
Hydration of the whole page | The browser runs a lot of JavaScript before it can respond | Static content as server components; small client islands |
Heavy click handlers | Menus, filters or tabs doing too much work synchronously | Update the UI first, then do the work |
Consent and A/B testing scripts | Run early and often block rendering or listeners | Load once, lean config, server-side testing |
Frameworks don't protect you on their own. Field data published by corewebvitals.io for the second quarter of 2026 shows only about two-thirds of Next.js sites passing INP, with a median around 236ms. The pattern we see is the same across platforms: what gets loaded on top of the site matters more than the framework underneath.
How do you find which interactions are slow?
Find slow interactions by combining field data, which tells you which pages fail, with lab profiling, which tells you why. Don't start optimizing before you know which interaction and which phase is slow.
Find failing pages in Search Console
The Core Web Vitals report groups URLs that fail INP on mobile and desktop. Start with the group that has the most traffic.
Add attribution to real-user data
Use the attribution build of Google's web-vitals library, or your monitoring tool, to log which element was clicked and which scripts were running.
Reproduce on a throttled phone profile
In Chrome DevTools, record a performance trace with CPU throttling, perform the slow interaction and look at the interactions track.
Split the time into three phases
Input delay means something else was running; processing time means your handler is slow; presentation delay means rendering the update is expensive.
Attribute long tasks to a source
Look at which script owns the long tasks around the interaction. Third-party domains in the call stack are a strong hint.
Fix the biggest source, then remeasure
Change one thing at a time and confirm in the lab, then in field data after it rolls through the 28-day window.
If lab and field numbers disagree, that's normal; our guide to PageSpeed Insights scores vs real-user data explains why and which to trust.
How do you fix INP caused by third-party scripts and widgets?
Fix third-party INP problems by removing what you don't use, delaying what you do, and loading widgets only when someone wants them. This is usually the biggest and cheapest INP win on a marketing site.
- Audit the tag manager. List every tag, its owner and whether anyone still reads its data. Old pixels from past campaigns are common.
- Delay non-essential tags until the page is idle or until the first interaction has been handled.
- Use facades for chat, video and calendars. Show a static button or thumbnail; load the real script on click.
- Avoid duplicate analytics. Two analytics tools firing the same events doubles the work for no extra insight.
- Move experiments server-side where possible, instead of client-side testing scripts that run on every page.
Our method for a full third-party scripts audit shows how to measure each tag's cost and how to get marketing sign-off to remove it.
How do you fix INP caused by animation?
Fix animation-related INP by animating only transform and opacity, limiting effects that run on every scroll frame, and pausing anything off-screen. Animation hurts INP when it keeps the main thread busy at the moment someone taps.
Scroll-linked effects built in JavaScript are the usual problem. Where possible, use CSS transitions, CSS scroll-driven animations or a library that runs on the compositor. Avoid animating width, height, top or left, which force layout. Pause looping animations, Lottie files and videos when they're out of view. And keep hover effects cheap, since a heavy hover handler on a large grid fires constantly.
Hypothetical example: a feature page with a heavy scroll story
For example, suppose a product page uses a scroll-driven story where a JavaScript listener recalculates positions for a dozen elements on every scroll event, and the page also loads a chat widget and three marketing tags.
A profile shows taps on the navigation waiting behind both the scroll work and the widget initialization. The fix keeps the design but changes the method: the scroll effects move to CSS scroll-driven animations on transform and opacity, the chat becomes a click-to-load facade, and the tags load after idle. The visitor sees the same story, and the main thread is free when they tap.
How do you fix INP caused by hydration and heavy JavaScript?
Fix hydration-related INP by shipping less JavaScript to the browser and splitting the work that remains. On React and Next.js sites, keep static content as server components and make only the interactive parts client components.
- Shrink client components. A whole section marked as client code hydrates every child; move the interactive bit into its own small component.
- Lazy load below-the-fold interactivity such as carousels, calculators and pricing toggles.
- Update the screen first. In click handlers, show the visual change immediately and defer analytics or heavy work.
- Yield in long tasks. Break big loops into chunks and yield to the browser, using scheduler.yield where supported or a timeout fallback.
- Avoid layout thrashing. Don't read layout and then write styles repeatedly inside one handler.
Our deep dive on improving INP on Next.js sites covers client components and hydration in detail, and Core Web Vitals for Framer, Webflow and Next.js covers builder-specific controls.
How do you stop INP from regressing?
Stop INP from regressing by putting a gate on new scripts and heavy components, and by checking field data on a schedule. INP problems come back because marketing sites keep adding things.
Agree a rule that every new tag has an owner, a reason and a removal date. Build widgets into components that load on interaction by default, so nobody can add a chat script to the head by accident. Review the Core Web Vitals report monthly. If you'd rather hand the whole problem to a team, our guide to website speed optimization services explains how to scope the work around real-user targets.
