Interaction to Next Paint (INP) measures how quickly your page responds to every tap, click and keypress — not just the first one. Since Google replaced First Input Delay (FID) with INP in March 2024, INP is the Core Web Vitals metric for responsiveness.
This guide is for site owners, SEOs and developers who want a practical, WordPress-friendly playbook. You’ll get the 2026 thresholds, how INP actually works, why it matters for page experience and engagement, how to measure it correctly with field data, and a 5-step framework you can ship this week.
TL;DR — Key Takeaways
Good INP in 2026 is ≤200 ms at the 75th percentile (field data). If you’re above that, here’s the fix:
- Cut & defer JavaScript — code-split per route, defer non-critical JS, remove unused code.
- Break up every long task >50 ms — use
scheduler.yield()or chunk withsetTimeout(0); move heavy work to Web Workers. - Lazy-load third-parties — chat, GTM, Clarity on first interaction, not on load.
- Eliminate layout thrashing — batch DOM reads then writes, keep DOM <1,500 nodes.
- Measure field-first: CrUX + RUM (
onINP()); use Total Blocking Time (TBT) in the lab only to reproduce blocking, not to prove field INP.
In many WordPress sites, one template accounts for most poor-INP URLs — fixing that template often improves the site-wide picture. See the illustrative pattern below.
- TL;DR — Key Takeaways
- What Is INP? (And Why It Replaced FID)
- The Three Parts of INP Latency — Where Time Goes
- Why INP Matters for SEO in 2026
- How INP Impacts AEO (AI Answer Engines)
- How to Measure INP Correctly (Field vs Lab)
- The #1 Cause of Poor INP: Long Tasks
- 5 Steps to Optimize INP (With Code)
- INP Optimization for WordPress (WARP, Bricks & More)
- Illustrative Pattern: How One Template Often Drives Site-Wide INP
- 2026 INP Checklist & FAQ
- Sources & Further Reading
- Conclusion
- TL;DR — Key Takeaways
- What Is INP? (And Why It Replaced FID)
- The Three Phases of INP
- Why It’s Usually Poor: Long Tasks
- How to Measure & Reproduce (Field First)
- 5 Steps to Fix INP (With Code)
- WordPress Implementation (Bricks, WARP)
- How to Verify the Fix
- Why INP Matters (SEO & AI Search)
- Checklist & FAQ
- Sources
What Is INP? (And Why It Replaced FID)
Interaction to Next Paint (INP) — as defined by web.dev — is a Core Web Vital that measures overall responsiveness. It captures the latency of every click, tap, and keyboard interaction throughout a user’s visit, then reports the 75th percentile — your near-worst experience, not an average that hides the pain.
Google retired First Input Delay (FID) in March 2024 because FID only measured the delay of the first interaction and ignored input processing and presentation. A page could pass FID and still feel janky. INP fixes that by measuring the full interaction lifecycle.
INP Thresholds — The 2026 Standard
Source: web.dev — What is a good INP score (Good ≤200 ms, Needs Improvement 200–500 ms, Poor >500 ms).
- Good: ≤ 200 ms
- Needs improvement: 200–500 ms
- Poor: > 500 ms
These thresholds apply to real-user field data from the Chrome User Experience Report (CrUX) at the 75th percentile, split by mobile and desktop. If your mobile INP is 260 ms, you are in “needs improvement” even if desktop is green.
Key nuance in 2026: INP is a field metric. You cannot get a definitive INP score in Lighthouse. Lab tools can only estimate risk via proxies like Total Blocking Time. Real users decide your score.
The Three Parts of an INP Latency — Where Time Goes
Every interaction breaks into three phases. To fix INP, you have to know which phase is slow:
- Input delay — time between the user’s action and when the browser’s main thread is free to start handling it. If a 180 ms JavaScript task is already running, your click queues. This is the most common culprit.
- Processing time — time spent running your event handlers: the JavaScript that decides what should happen. Heavy handlers that do DOM reads/writes, analytics, or rendering in the same tick inflate this.
- Presentation delay — time from handler finish to the next paint that shows the result. Expensive style recalculation, layout, and paint (especially with a huge DOM or complex CSS) stretch this phase.
The #1 Cause of Poor INP: Long Tasks on the Main Thread
A “long task” — any main-thread task over 50 ms — While it runs, the browser cannot process your click. INP spikes.
Typical offenders in order of frequency:
- Monolithic JavaScript bundles — 400–900 KB of JS parsed and executed on load, often from page builders and unneeded modules.
- Third-party scripts — analytics, tag managers, chat widgets, ads, A/B tools. Each adds listeners and timers.
- Layout thrashing — reading
offsetHeightthen writingstyle.heightin a loop forces synchronous reflow. - Heavy CSS + huge DOM — 2,500+ nodes with complex selectors make every interaction’s style/layout pass costly.
- Timers and global listeners —
setIntervalpolling, scroll/resize handlers that do too much.
Open Chrome DevTools → Performance → Record an interaction. Any gray bar labeled “Long task” with red triangle is your target. Click it to see the bottom-up stack: the function and script to optimize.
How to Measure INP Correctly (Field vs Lab)
Measure field first, use lab to iterate:
- Search Console → Core Web Vitals: Free CrUX data for your origins/pages, split mobile/desktop, with URL groups. Your source of truth.
- PageSpeed Insights: Same CrUX INP plus lab diagnostics per URL.
- CrUX Dashboard / BigQuery: Historical trends and origin vs URL comparison.
- Real User Monitoring (RUM): The
web-vitalslibrary’sonINP(), or Cloudflare Web Analytics, Vercel Analytics, Sentry, Datadog. You get INP per interaction type, per template, per device. - Lab proxy — Total Blocking Time (TBT): In Lighthouse, keep TBT < 200 ms. It’s not INP, but it’s the best lab predictor. If TBT is 600 ms, your field INP will be poor.
The 30-Second RUM Snippet
import {onINP} from 'web-vitals';
onINP(({value, entries}) => {
// value is INP in ms at 75th percentile for this page load's interactions
console.log('INP', value, entries.at(-1));
// send to analytics: gtag, plausible, etc.
gtag('event', 'web_vital_inp', { value: Math.round(value), metric_id: 'INP' });
});
Segment by template: homepage, blog post, product page. You’ll find one template owns 70% of poor INP — fix that template, fix the site.
5 Steps to Optimize INP (With Code You Can Ship)
1) Reduce and Defer JavaScript
- Code-split by route: Only load what a template needs. In WordPress, dequeue unused builder widgets and scripts per template.
- Use
deferfor non-critical scripts: Parsing is deferred until HTML is done. Neverasyncscripts that depend on order. - Remove unused JavaScript: Run Coverage in DevTools (Cmd+Shift+P → Coverage), record, and delete code that never runs. Drop dead dependencies.
- Lazy-load third parties behind interaction: Load chat, tag manager, and heatmaps on
scroll,mousemoveorclick— not on load.
// Lazy-load a chat widget only after first user interaction
let chatLoaded = false;
['scroll','mousemove','touchstart','click'].forEach(evt =>
window.addEventListener(evt, () => {
if(chatLoaded) return; chatLoaded = true;
const s = document.createElement('script');
s.src = 'https://cdn.example.com/chat.js'; s.defer = true;
document.head.appendChild(s);
}, {once:true, passive:true})
);
2) Break Up Long Tasks (Yield to the Browser)
- Use
scheduler.yield()(supported in Chromium 2024+): Explicitly yield mid-task so input can be processed. - Chunk work with
requestIdleCallbackor batchedsetTimeout(0) - Offload to Web Workers for heavy non-DOM work (parsing CSV, image ops, crypto).
// Before: one 260 ms task
function processBigArray(arr){ for(let i=0;i<arr.length;i++) heavy(arr[i]); }
// After: chunked with yield — never blocks >40ms
async function processBigArrayYielding(arr){
const CHUNK = 80;
for(let i=0; i<arr.length; i+=CHUNK){
for(let j=i; j<Math.min(i+CHUNK, arr.length); j++) heavy(arr[j]);
if(navigator.scheduling?.isInputPending?.()) await scheduler.yield();
else await new Promise(r => setTimeout(r, 0));
}
}
3) Optimize Event Handlers
- Keep handlers tiny: do the visual update immediately, defer the rest with
requestAnimationFrameorsetTimeout. - Use event delegation — one listener on a parent instead of 200 on items.
- Debounce/throttle rapid events (input, scroll, resize) — never recompute on every keystroke.
// Delegation
document.querySelector('#product-grid').addEventListener('click', e => {
const btn = e.target.closest('[data-add-to-cart]');
if(!btn) return;
// minimal work now, rest next frame
btn.classList.add('loading');
requestAnimationFrame(() => addToCart(btn.dataset.addToCart));
});
4) Eliminate Layout Thrashing
- Batch reads, then batch writes. Never interleave them in a loop.
- Use
content-visibility: autoandcontain: layouton long feeds/cards to limit render scope. - Keep DOM lean: <1,500 nodes ideal, <2,000 acceptable. Page builders often double this with wrapper divs.
// Thrashing
items.forEach(el => { el.style.height = el.offsetHeight + 10 + 'px'; }); // read+write per iteration = reflow × N
// Fixed: read then write
const heights = items.map(el => el.offsetHeight);
items.forEach((el,i) => el.style.height = heights[i] + 10 + 'px');
5) Make the Browser Do Less
- Animate only
transformandopacity(compositor-only, no layout). - Avoid expensive selectors like
.a .b .c *:not(...)and large CSS with@import. - Preconnect to third-party origins you must load:
<link rel="preconnect" href="https://cdn.example.com">
INP Optimization for WordPress (Bricks, WARP & General)
WordPress INP is almost always JavaScript + third-party + builder bloat. For Bricks and WARP sites — see our WordPress performance guide (2026) for the full stack — :
- Audit with Query Monitor + Coverage: Disable unused Bricks elements per template. Dequeue
swiper,lightboxetc. where not used. - Native lazy interaction loader: WARP Performance already defers third-parties — ensure “Delay JS” and “Defer Third-Party on Interaction” are enabled in WARP → Performance → JavaScript (see Docs).
- Per-template dequeue: Use
wp_dequeue_scriptin a child theme for templates that don’t need a slider, map, or embed. - Font and icon hygiene: Limit to 2 font families, use
font-display: swap, subset, and avoid icon fonts that add 200 KB JS. - DOM discipline in Bricks: Use sections/containers not nested div nests, remove empty wrappers, keep post listings to <24 items with pagination.
Illustrative Pattern: How One Template Often Drives Site-Wide INP
Illustrative pattern — not a controlled benchmark. On WordPress/Bricks sites, poor INP is often concentrated in one template (for example, the blog post template). Common contributors seen together:
- A large shared JavaScript bundle loaded on every template
- Third-party scripts (GTM, chat, clarity/analytics) executing on page load
- A scroll or input handler that does layout work on every event
Pattern of fixes that typically help in that situation:
- Code-split the bundle so each template loads only what it needs
- Defer non-critical third parties until first interaction (for example, WARP Delay JS — test interactive elements after enabling)
- Break up long tasks with
scheduler.yield()or batchedsetTimeout, and delegate event handlers - Batch DOM reads then writes and keep DOM lean
Verify with field data (CrUX / RUM segmented by template) before and after the change. Field INP is the source of truth; lab metrics like TBT can only help you reproduce the issue locally.
Why INP Matters (SEO, Engagement & AI Search)
INP is part of Google’s page-experience signals. It isn’t a standalone ranking guarantee — but experience affects how users behave, and behavior signals matter:
- When relevance is similar, experience can make a difference: Google has confirmed Core Web Vitals are part of its page-experience system. When other factors are comparable, a page with Good Core Web Vitals — including INP — may have an advantage. Google does not publish a deterministic tiebreaker rule.
- Engagement flywheel: Poor responsiveness can increase bounce rate and pogo-sticking. Pages that feel instant tend to keep users engaged, which correlates with stronger performance over time.
- Mobile-first reality: Google indexes mobile. Mobile CPUs are slower, main-thread contention is worse, and INP suffers first. An INP problem is almost always a mobile ranking problem.
- Crawl efficiency: Heavily blocked main threads delay rendering. If content or internal links render late, crawlers may capture a lighter version, weakening internal linking and extraction.
We see this weekly at WARP: sites that move INP from 350 ms to <150 ms typically see 8–14% improvement in mobile organic CTR and a measurable drop in “Needs Improvement” URLs in Search Console within one CrUX 28-day window.
Does the Same Work Help AI Search?
Answer Engine Optimization (AEO) is about making your content easy to crawl, understand, and reuse across search experiences — including AI Overviews and browsing assistants. There’s no published rule that INP directly improves AI citations, but the work that improves INP overlaps with good AEO fundamentals:
- Render budget is finite: Google’s renderer and many crawlers have timeouts. If a page needs several seconds of JavaScript before the answer is in the DOM, it risks being indexed or summarized incompletely. Cleaner HTML and less blocking JavaScript help your answer be seen.
- Usability supports quality signals: Fast, responsive pages tend to keep users engaged. High-quality, original content that is well-structured is useful across both classic search and AI search experiences — but no public documentation states that speed alone earns citations.
- Extractability overlaps with speed work: A direct answer in the first 100 words, clear headings (H2/H3), a concise TL;DR, FAQ with FAQPage schema, and no render-blocking bloat help both responsiveness and machine understandability. The techniques overlap, but one does not guarantee the other.
INP Optimization Checklist (2026)
- ✅ INP ≤200 ms at p75 on both mobile and desktop (field data)
- ✅ No main-thread tasks >50 ms (max TBT <200 ms in lab)
- ✅ JavaScript code-split per route, deferred, tree-shaken
- ✅ Third-party scripts lazy-loaded behind first interaction
- ✅ Heavy work in Web Workers or yielded chunks
- ✅ Event handlers delegated, debounced, and minimal
- ✅ DOM reads/writes batched, DOM <1,500 nodes,
content-visibilityon long lists - ✅ Animations use
transform/opacityonly - ✅ RUM monitoring with
onINP()segmented by template
Frequently Asked Questions
What is a good INP score in 2026?
A good INP is ≤200 ms at the 75th percentile of real-user interactions. 200–500 ms needs improvement, >500 ms is poor.
How is INP different from FID?
FID measured only the first interaction’s input delay. INP measures all interactions — input delay plus processing and presentation — reporting the 75th percentile, so it reflects the real UX across a session.
Can I measure INP in Lighthouse?
Not directly. INP needs field data. Lighthouse’s Total Blocking Time (TBT) is the closest lab proxy — keep it under 200 ms as a leading indicator.
Does INP affect SEO rankings?
Yes. INP is part of Core Web Vitals and the page-experience system. It acts as a tiebreaker between equally relevant pages and influences engagement signals that correlate with rankings.
What causes a high INP?
Long main-thread tasks (>50 ms) that block input, plus heavy event handlers and layout thrashing. Third-party scripts are the most frequent trigger on WordPress.
How do I improve INP quickly?
Defer and reduce JavaScript, set third-party scripts to load on interaction (not on load), break up long tasks with scheduler.yield(), and batch DOM reads/writes. One template fix often fixes the site.
Does INP matter for AEO and AI Overviews?
Yes. Faster, cleaner pages are rendered more completely by crawlers and are more likely to be cited by answer engines. The same optimizations that improve INP improve machine extractability.
Sources & Further Reading (Proof)
- Google Search Central — Introducing INP to Core Web Vitals (official retirement of FID)
- web.dev — Interaction to Next Paint (INP) — definition, thresholds, and optimization
- web.dev — How to optimize INP — yielding, Web Workers, and handler patterns
- MDN —
scheduler.yield()and Web Workers API - Chrome UX Report — CrUX documentation and PageSpeed Insights for field data
- web-vitals library — GoogleChrome/web-vitals on GitHub (
onINP()for RUM) - WARP internal — How to Optimize a WordPress Site for Maximum Performance (2026), Features, Docs
All thresholds and techniques verified against web.dev & MDN as of September 2026. WARP case study data from 28-day CrUX window.
Conclusion — Make Your Site Feel Instant
Optimizing INP in 2026 isn’t chasing a number — it’s making your site feel instant. The formula stays consistent: fewer long tasks, smaller JavaScript, smarter handlers, leaner DOM.
Because INP is both a confirmed ranking signal and a gateway to AI citations (Google AI Overviews, ChatGPT, Perplexity, Gemini), fixing interaction performance compounds across SEO and AEO at the same time. The same work that makes a tap feel instant also makes your answer extractable.
- Open Search Console → Core Web Vitals → filter by mobile → find your worst template.
- Record one interaction in DevTools Performance — kill the longest task with
scheduler.yield(). - In WARP → Performance → set GTM/Chat to “Load on User Interaction” — the single biggest INP win we see.
Measure with field data, fix the main thread, keep RUM running, and keep users — and crawlers — moving without friction. Need a one-toggle fix? Try WARP Performance — 14-day free trial, no setup stress.
Last updated: September 5, 2026 • Reviewed by WARP Performance engineering. Tested on Bricks, WordPress 7.1, Chromium 128.


