A poor Interaction to Next Paint (INP) score means your pages are slow to respond after a visitor clicks, taps or presses a key. The cause is almost always JavaScript: too much of it running on the main thread when someone tries to use the page.
Our Core Web Vitals guide explains the three metrics and the 200 millisecond target. This piece goes one level down. It walks through how to find the exact interaction that is slow, which of its three phases is the problem, the usual culprits on WordPress and Drupal sites, and the fix for each phase.
The short version: confirm the problem in Search Console or PageSpeed Insights, then use the web-vitals library or Chrome DevTools to name the slow element and its slow phase. On most CMS sites the cause is third-party scripts, an overloaded tag manager, a chat widget or a page builder’s large DOM. Load less script, load it later, and break long tasks up.
What Interaction to Next Paint measures, phase by phase
Interaction to Next Paint times every click, tap and key press during a visit, from the input until the browser paints the next frame. According to web.dev’s INP article, each interaction has three phases. Input delay is the wait before any event handler starts. Processing duration is the time the handlers take to run. Presentation delay is the time from the handlers finishing until the frame appears.
Knowing which phase is slow tells you where to look.
| Phase | What it means | Common cause on CMS sites | Usual fix |
|---|---|---|---|
| Input delay | The main thread is busy when the visitor acts | Third-party scripts, tag manager work, timers | Remove, delay or defer scripts |
| Processing duration | The click handler itself is slow | Theme or plugin code doing too much at once | Update the screen first, then yield |
| Presentation delay | Rendering the next frame takes too long | Large DOM from page builders, big HTML injected by script | Smaller DOM, content-visibility |
Step 1: Confirm the problem in field data
Start with real visitors. Most lab tools, Lighthouse included, load the page without clicking, so they cannot measure Interaction to Next Paint.
In Search Console, the Core Web Vitals report groups similar URLs and shows a Group INP value for each. It means 75% of visits to URLs in the group were that fast or faster over the last 28 days. Click an example URL to see other pages in the group, ordered by impressions. Our Search Console walkthrough for traffic drops shows where this report fits.
PageSpeed Insights shows INP from the Chrome UX Report (CrUX) for one URL, with mobile and desktop toggles.
Both tools tell you whether there is a problem, not what causes it. web.dev’s guide to finding slow interactions in the field makes the same point about CrUX. For the cause, you need your own field data.
Step 2: Find the slow interaction with the attribution build
Google’s open source web-vitals library measures INP in real visitors’ browsers. Its attribution build adds the details you need to fix it.
import {onINP} from 'web-vitals/attribution';
onINP(({value, attribution}) => {
console.log(value, attribution.interactionTarget,
attribution.inputDelay, attribution.processingDuration,
attribution.presentationDelay);
});
In production, send those values to your analytics tool or a logging endpoint. The fields that matter most:
- interactionTarget: a CSS selector for the element used, such as the menu toggle or the donate button.
- inputDelay, processingDuration, presentationDelay: the three phases, in milliseconds.
- loadState: whether the page was still loading.
- longestScript: the longest script running during the interaction, from Long Animation Frame data.
That last field often names the plugin or vendor script at fault. It relies on a Chromium API, so it only comes from visitors on browsers such as Chrome and Edge.
One limit matters for our readers. The README says the library cannot see inside iframes, while CrUX includes iframe content. Donation forms, event widgets and video players often load in iframes. If CrUX shows poor INP and your own data looks fine, check the iframes.
Step 3: Reproduce the interaction in Chrome DevTools
Once you know the element, reproduce the problem. Open the Performance panel in DevTools. According to Chrome’s Performance panel documentation, its live metrics view shows your local INP and logs each interaction with its target.
Set CPU throttling first. Your laptop is much faster than the phone behind the 75th percentile visit. The documentation suggests a 20x slowdown or a calibrated mobile preset.
Then record a trace while you repeat the slow interaction. Chrome’s Performance features reference explains what to look for:
- The Interactions track marks interactions over 200 milliseconds with a red triangle.
- Long tasks also get a red triangle, with the part beyond 50 milliseconds shaded red.
- The Summary tab’s 1st / 3rd party table shows main thread time by vendor.
web.dev’s INP optimization guide adds a useful tip: interact while the page is still loading. A visitor who taps the menu in the first few seconds hits every startup script at once.
The usual Interaction to Next Paint culprits on CMS sites
On the nonprofit, association and university sites we see, the same few things cause most poor scores.
Tag managers. web.dev’s tag manager best practices report a correlation between larger tag managers and poorer INP. Old campaign tags pile up, and many click and timer triggers add more work.
Chat, survey and feedback widgets. These often load a large script on every page and keep running after load.
Consent banners. They run on the first interaction many visitors make. The same web.dev guide says cookie notices should not load through a tag manager. Our Consent Mode v2 guide covers how the banner and tags fit together.
Page builders. Builders tend to wrap content in many nested elements. Lighthouse’s DOM size audit warns at about 800 body nodes and errors at about 1,400.
Plugins and modules that load everywhere. A slider, form or map script on every page adds startup work even where it is not used.
Fixing input delay: less script, loaded later
On CMS sites, input delay is the phase that most often drags down Interaction to Next Paint. The fixes are mostly removal.
- Audit the tag manager. Pause or delete unused tags, which web.dev recommends over blocking them with trigger exceptions. Fire non-essential tags after the window has loaded.
- Load widgets only where needed. A chat widget for the contact page does not need to load on every article.
- Use a facade. Chrome’s Lighthouse docs describe a facade as a static stand-in that loads the real embed on click, and list live chat widgets as an example.
- Defer your own scripts. A deferred script does not block parsing, so less work lands on the main thread during load.
Fixing processing time: update the screen, then yield
If processing duration is the slow phase, the click handler does too much before the browser can paint. Show the visual response first and move the rest into a later task.
web.dev’s guide to long tasks calls this yielding to the main thread. It defines a long task as any task over 50 milliseconds. Its recommended tool is scheduler.yield(), which pauses your function, lets the browser handle more important work, then resumes your code ahead of other queued tasks.
Not every browser supports it, so use a fallback. This pattern follows the approach web.dev describes:
function yieldToMain() {
if (globalThis.scheduler?.yield) return scheduler.yield();
return new Promise((resolve) => setTimeout(resolve, 0));
}
button.addEventListener('click', async () => {
showSpinner(); // visual response first
await yieldToMain(); // let the browser paint
submitForm(); // slower work after
});
The setTimeout fallback still yields but loses the priority. Chrome’s scheduler.yield() article also lists a polyfill package. web.dev’s INP guide adds two more fixes: avoid reading layout right after changing styles, and push non-urgent work such as autosave past the next frame.
Fixing presentation delay: a smaller page to render
web.dev’s INP guide says large DOMs increase rendering work, both on first load and during interactions. On CMS sites, the practical fixes are:
- Rebuild the busiest page builder templates with fewer nested wrappers.
- Cut mega menus and off-screen panels that render hundreds of links on every page.
- Use the CSS
content-visibilityproperty on long sections below the fold. - Avoid injecting large blocks of HTML with JavaScript when a visitor clicks.
Deferring scripts in WordPress and Drupal
WordPress. Since WordPress 6.3, scripts can be registered with a loading strategy. According to the core dev note, you pass 'strategy' => 'defer' or 'async' in the args array of wp_enqueue_script(). WordPress treats it as a request. If a dependent script is blocking, or an inline script is attached after it, the script stays blocking. One old plugin can undo a theme’s careful deferring.
Drupal. Drupal loads JavaScript in the footer by default, according to Drupal’s libraries.yml documentation. You can add defer or async through an attributes entry. The bigger gain is scope. A library listed in the theme’s info file loads on every page. One attached with attach_library() in a Twig template loads only where it is used.
Interaction to Next Paint tools as of October 2026
The tools change faster than the metric. These details were checked against the vendors’ pages in October 2026.
| Item | Status as of October 2026 | Source |
|---|---|---|
scheduler.yield() |
Chrome and Edge 129, Firefox 142; not Safari | web.dev long tasks guide |
| Long Animation Frames API | Chrome and Edge 123; not Firefox or Safari | web.dev field guide |
| web-vitals library | Version 5 in the README’s CDN examples | GitHub README |
| Lighthouse DOM size audit | Moved into the Optimize DOM size insight in Lighthouse 13 | Chrome Lighthouse docs |
After a fix ships, start validation in Search Console and allow about 28 days for the report to catch up. Our technical SEO foundations cover how speed fits with the rest of search health.
Frequently Asked Questions
What is a good Interaction to Next Paint score?
200 milliseconds or less at the 75th percentile of real visits is good. Over 500 milliseconds is poor. Mobile and desktop are assessed separately.
Why does Lighthouse not show Interaction to Next Paint?
Lighthouse loads the page without clicking anything, so there is no interaction to measure. Use Total Blocking Time as a lab hint and field data for the real score.
How do I find which element causes a poor INP score?
Log the interactionTarget field from the web-vitals attribution build, or use a real user monitoring tool. In the lab, the DevTools Performance panel logs each interaction and its target.
Does Google Tag Manager hurt Interaction to Next Paint?
It can. web.dev reports a correlation between larger tag managers and poorer INP. Remove unused tags, simplify triggers and fire non-essential tags after load.
Should I use scheduler.yield() on a production site?
Yes, with a fallback. web.dev’s support table lists Safari as unsupported, so check for it and fall back to setTimeout.
Why is INP poor in Search Console but fine in my own tests?
Your tests likely run on a fast machine without throttling. The slow interaction may happen during load, and iframe content counts in CrUX but is invisible to the web-vitals library.
Will a caching plugin fix Interaction to Next Paint?
Usually not. Caching speeds up delivery of the HTML, which helps LCP. INP depends on JavaScript work in the browser after the page arrives.
Do WordPress page builders cause poor INP?
They can, through a large DOM and scripts loaded on every page. Trim nesting on the busiest templates and load builder widgets only where they are used.