WordPress INP: How I Get Interactions Under 200ms
WordPress INP measures how fast your pages respond to clicks, taps, and key presses, and a good score is under 200 milliseconds. I fix it by cutting main-thread JavaScript, deferring third-party tags, breaking long tasks, and trimming builder and cart scripts so the browser can paint the next frame faster.
WordPress INP measures how fast your pages respond to clicks, taps, and key presses, and a good score is under 200 milliseconds. I fix it by cutting main-thread JavaScript, deferring third-party tags, breaking long tasks, and trimming builder and cart scripts so the browser can paint the next frame faster. If I were checking this on a real site, I'd start with the page that earns traffic or money, confirm whether the issue is backend, frontend, content, or layout related, then apply one fix at a time.
What is WordPress INP?
WordPress INP, short for Interaction to Next Paint, is a Core Web Vitals metric that measures how long your site takes to visually respond after someone clicks, taps, or presses a key. It records the slowest meaningful interaction across a whole visit, then reports the value at the 75th percentile of your real users. A good INP is 200 milliseconds or less, 200ms to 500ms needs improvement, and anything over 500ms is poor.
INP replaced First Input Delay in March 2024, and that swap is why so many sites suddenly started failing. FID only timed the delay before the first interaction's handler ran. INP times the entire interaction: the input delay, the event handler processing, and the presentation delay before the next frame paints. So a menu that opens late, a filter that stutters, or an add-to-cart button that freezes for half a second now counts against you.
Here's the part people miss: INP is a frontend, main-thread problem, not a hosting problem. Faster servers and caching help your WordPress TTFB and load metrics, but they barely touch how fast a click feels. INP lives in JavaScript, and WordPress ships a lot of it through plugins, page builders, and tracking tags. That's what we'll cut down.
Why do WordPress sites fail INP so often?
WordPress sites fail INP because they stack far more JavaScript on the main thread than a single interaction needs. Every active plugin, page builder, slider, popup, chat widget, and analytics tag can register its own event listeners and queue its own work. When you click something, all that code competes for one thread, and the browser can't paint the next frame until it clears.
The browser breaks that work into tasks, and any task running longer than 50 milliseconds is a long task. Long tasks are the core of poor INP. If a user clicks while a 300ms script is mid-run, their click sits in a queue until that task finishes, so the interaction feels stuck even though nothing is technically broken. Total Blocking Time, which you'll see in Lighthouse, is the lab proxy for this same main-thread congestion.
Logged-in and dynamic pages are usually worst. An editor running Elementor, WooCommerce, a security plugin, and a form builder can carry three or four times the script weight of a static blog post. That's why I always test the real interactive pages, not just the homepage. If you want the bigger picture of where this bloat comes from, the WordPress Core Web Vitals pillar maps how INP fits alongside LCP and CLS.
How do I diagnose what's hurting my INP?
Diagnose INP by combining field data, a lab trace, and a script inventory, because no single tool tells the whole story. Start with PageSpeed Insights and the Chrome User Experience Report (CrUX) to confirm your real-world INP and which device fails. Field data shows you the truth; lab tools show you the cause.
Next, open Chrome DevTools, switch to the Performance panel, set CPU to a 4x or 6x slowdown to mimic a mid-range phone, then record while you actually click your menus, filters, and forms. Long tasks show up as red-flagged blocks, and you can expand one to see exactly which script and function ate the time. This is where you stop guessing and find the real offender.
Then inventory the scripts. Query Monitor lists every enqueued script and the plugin that loaded it, so you can spot a chat widget or a slider library loading on pages that don't use it. Compare a logged-out page against a logged-in one too, since admin-bar and editor scripts often double the main-thread work. For a repeatable run, I follow the WordPress speed audit checklist so nothing gets skipped.
How do I reduce and defer JavaScript for better INP?
Reduce and defer JavaScript by cutting what loads, deferring what's left, and delaying anything that isn't needed for the first interaction. This is the single biggest lever for WordPress INP because main-thread JavaScript is what blocks the next paint. Start by removing or replacing plugins that enqueue heavy scripts sitewide when only one page uses them.
Delay JavaScript execution is the strongest setting in caching plugins like WP Rocket, Perfmatters, and FlyingPress. It holds non-critical scripts until the user moves, scrolls, or taps, so analytics, chat, sliders, and embeds stop competing with that first click. Deferring loads scripts after HTML parsing finishes, while delay waits for actual user intent, and delay is the one that moves INP most. Just exclude anything required for the first interaction, like a sticky menu's toggle or a search box handler, or you'll trade INP for broken buttons.
Then trim the dead weight. Remove unused JavaScript by dequeuing plugin scripts on pages that don't need them, which Perfmatters Script Manager and Asset CleanUp both do per-URL. Minify and combine carefully on HTTP/2 hosts, since combining can sometimes hurt more than it helps. The goal isn't a smaller download, it's less code executing during interactions.
How do I break up long tasks that block clicks?
Break up long tasks by splitting any main-thread job over 50 milliseconds into smaller chunks that yield control back to the browser. When a task yields, the browser can slot in a pending click and paint a response instead of making the user wait for the whole job to finish. This is the technique most WordPress guides mention but few explain in plain terms.
In custom code, you yield by wrapping non-urgent work in a short timeout or by awaiting scheduler.yield() where it's supported, so the urgent visual update happens first and the secondary calculation runs after the next paint. Most site owners won't write this themselves, but you can ask a theme or plugin developer to defer secondary work, and you can choose plugins that already chunk their own scripts. Lighter, well-built tools simply create fewer long tasks.
Debouncing handlers is the practical win here. A live search or filter that fires on every keystroke can queue dozens of tasks; debouncing it to run once after a short pause cuts that to one. The same applies to scroll and resize listeners. If a third-party widget is the culprit and you can't change its code, delaying it until interaction is the cleaner fix, which loops back to the JavaScript discipline above.
How do third-party scripts wreck INP, and how do I tame them?
Third-party scripts wreck INP because they run code you don't control on your main thread, and they often add their own event listeners on top of yours. Tag managers, chat widgets, ad networks, A/B testing tools, consent banners, and social embeds are the usual suspects, and one heavy tag can push an otherwise fast page past 200ms on mobile.
Tame them with a simple rule I use on every audit: nothing third-party loads before user intent unless it's legally or visually required. Delay analytics, pixels, chat, and embeds until the first scroll or tap. Load Google Tag Manager through delay JavaScript, or move tags to Cloudflare Zaraz so they run off the browser's main thread entirely. Replace heavy YouTube iframes with a click-to-load preview image, which kills a large chunk of script weight before anyone even presses play.
Audit ruthlessly. Open DevTools, sort by script, and ask whether each third-party tag earns its INP cost. I've cut a site's mobile INP from roughly 380ms to under 180ms just by delaying a chat widget and a heatmap script that the owner forgot was even installed. Third-party discipline is the fastest INP win that needs no redesign, and it pairs well with a tuned cache plugin configuration.
How do I fix INP on Elementor and Divi sites?
Fix builder INP by cutting the extra JavaScript that Elementor and Divi ship for animations, sliders, popups, and interactive widgets, since those features register handlers that fire on interaction. Page builders are convenient, but they trade a heavier main thread for that flexibility, and the cost shows up most on mobile clicks and taps.
On Elementor, enable the experiments that reduce script output, like optimized DOM output and loading widget scripts conditionally, and remove unused global widgets, popups, and motion effects. Heavy nested sections also inflate the DOM, which slows every interaction, so flattening structure helps both INP and rendering. The Elementor slow loading guide walks through the exact settings I change first.
On Divi, disable unused modules, turn off animations you don't need, and use Divi's built-in performance options to defer and dynamically load module JavaScript. For both builders, delay the non-critical scripts through your cache plugin and keep only the toggles users actually touch on first interaction. A builder site can absolutely hit a sub-200ms INP, but it takes trimming, not just a faster host.
Why is INP worse on WooCommerce stores?
INP is worse on WooCommerce stores because carts, filters, variations, and checkout fields run live JavaScript on the busiest pages your customers touch. Add-to-cart, quantity steppers, variation swatches, and AJAX filters all fire handlers on interaction, and they stack on top of WooCommerce's own scripts plus whatever your theme and builder add.
Cart fragments are the classic offender. WooCommerce refreshes the mini-cart with an AJAX call on nearly every page, which loads cart-fragments.js sitewide and adds main-thread work even on a blog post. I disable or limit cart fragments to cart and checkout pages where they're actually needed, which often drops INP on the rest of the store. The WooCommerce cart fragments guide covers the exact conditional load I use.
For checkout specifically, strip third-party tags from the funnel, lazy-load anything below the fold, and keep payment and shipping scripts lean so the fields stay responsive. Heavy checkouts feel slow precisely where it costs you money. If your store's interactions lag, the WordPress speed optimization service can profile each step and rebuild the slow ones.
What are the biggest INP mistakes people make?
The biggest INP mistake is testing visual load instead of real interactions, so people chase a green Lighthouse score while clicks still stutter. INP only moves when you exercise the actual menus, filters, forms, and cart buttons under CPU throttling. A page can load fast and still feel sluggish the moment someone taps something.
The second mistake is treating minification as the fix. Minifying JavaScript shrinks the download, but it doesn't reduce how long that code runs on the main thread, and execution time is what INP measures. I see owners minify, see no INP change, and assume the metric is broken when the real work, delaying and removing scripts, never happened.
The third mistake is ignoring third-party scripts because they look small in the network tab. A 40KB tag can spawn a long task far heavier than its file size suggests. Test on a real mid-range phone, not just your desktop, since most INP failures are mobile-only. Get those three habits right and you've avoided the failures behind most poor scores.
How do I confirm my INP fixes actually worked?
Confirm INP fixes with field data, because lab tools can't fully reproduce real-world interactions across devices and networks. After each change, re-record a DevTools Performance trace under 4x CPU throttling to confirm the long task you targeted is gone, then watch your 75th-percentile INP in CrUX and Google Search Console over the following weeks.
Field metrics lag, so don't panic if PageSpeed Insights still shows the old number the day after a fix. CrUX uses a rolling 28-day window, which means a real INP improvement can take three to four weeks to fully show up in the report. I tell clients to fix, verify in the lab immediately, then check the field data after a month before declaring victory.
For ongoing monitoring, real-user monitoring tools like DebugBear or the Web Vitals Chrome extension catch regressions when a new plugin or tag sneaks back in. INP isn't a one-time fix; every plugin update can add scripts. If you'd rather hand off the measurement and tuning loop entirely, that's exactly what a dedicated speed optimization service handles.
My checklist for WordPress INP Optimization
Test menus, forms, filters, add-to-cart, and checkout interactions.
Find long tasks in Lighthouse and Chrome Performance.
List scripts from builders, tracking, chat, forms, and plugins.
Check mobile CPU behavior.
Compare logged-out and logged-in interactions.