Interaction to Next Paint (INP) Fix: A Practical Guide to Boosting Responsiveness
If you’ve glanced at your Google Search Console Core Web Vitals report lately and seen a yellow or red flag for INP, you’re not alone. Interaction to Next Paint replaced First Input Delay as Google’s official interactivity metric in March 2024, and it has become the most common Core Web Vital that sites struggle to pass. The good news is that INP is measurable, understandable, and fixable. This guide walks you through what INP really measures, why it matters for both users and rankings, and exactly how to improve it with concrete techniques you can apply today.
What Interaction to Next Paint Actually Measures
INP captures the full latency of a user’s interaction from the moment they click, tap, or press a key until the browser paints the next visual frame that reflects that action. Unlike its predecessor FID, which only looked at the delay before the first interaction began, INP evaluates every interaction during a page visit and reports the worst (or near‑worst) latency. The metric is expressed in milliseconds and is evaluated at the 75th percentile of page loads, meaning three‑quarters of your users should experience an INP at or below the threshold.
Google’s current thresholds are:
- Good – ≤ 200 ms
- Needs improvement – 200 ms – 500 ms
- Poor – > 500 ms
A page that scores “good” feels instant to users; anything above 200 ms starts to feel sluggish, and beyond 500 ms users often perceive the page as broken.
Why INP Matters for SEO and Users
Google incorporates Core Web Vitals directly into its page experience ranking signal. Pages that consistently meet the INP threshold are more likely to rank higher when other factors are equal. Beyond the algorithm, INP has a direct impact on user behavior:
- Frustration and abandonment – Users expect visual feedback within roughly 100‑200 ms. Delays beyond that trigger repeat clicks, rage taps, and higher bounce rates.
- Conversion loss – Studies show each extra 100 ms of interaction latency can reduce conversions by ~ 7 %. Improving INP from 500 ms to 200 ms has been linked to double‑digit lifts in engagement and sales.
- Trust and perception – A responsive interface signals quality and reliability, encouraging repeat visits and longer sessions.
In short, optimizing INP isn’t just about checking a box for SEO; it’s about delivering a smoother, more satisfying experience that keeps people on your site and moving toward your goals.
How INP Differs from the Old FID Metric
First Input Delay only measured the time between a user’s first interaction and the moment the browser could start processing that interaction. It ignored everything that happened after the event handler began, and it completely overlooked later clicks, taps, or key presses. INP solves those blind spots by:
- Tracking all interactions – Not just the first one.
- Including the full response chain – Input delay (waiting for the main thread), processing time (running the handler), and presentation delay (painting the result).
- Reporting the worst‑case latency – This gives a realistic picture of the slowest experience a user might encounter, which is what actually drives frustration.
Because of this broader scope, many sites that once had “good” FID scores now see poorer INP numbers. The metric is harder to pass, but it also provides a far more accurate gauge of real‑world responsiveness.
The Three Phases of INP
Understanding INP’s three components helps you target the right fixes.
| Phase | What it covers | Typical culprits |
|---|---|---|
| Input delay | Time from user action until the event handler starts running. | Long JavaScript tasks, heavy third‑party scripts blocking the main thread, busy page‑load work (framework hydration, script evaluation). |
| Processing time | Duration the event handler itself takes to finish. | Complex calculations, synchronous DOM mutations, layout thrashing, heavy framework re‑renders. |
| Presentation delay | Time between handler completion and the next paint. | Large DOM size, forced synchronous layouts, expensive CSS rendering, off‑screen content that still triggers paint work. |
A slow INP can stem from any one of these phases, but in practice the processing phase is often the biggest contributor, especially on JavaScript‑heavy sites.
Common Causes of Poor INP
While every site is unique, several patterns appear repeatedly in field data and lab profiles:
- Long tasks – Any JavaScript execution that runs longer than 50 ms blocks the main thread, delaying both input and processing.
- Heavy event handlers – Handlers that do a lot of work (data fetching, complex validation, massive DOM updates) increase processing time.
- Layout thrashing – Alternating reads and writes to DOM properties forces the browser to recalculate layout repeatedly.
- Excessive DOM size – Pages with thousands of nodes make style, layout, and paint calculations more expensive.
- Third‑party script bloat – Analytics, ads, chat widgets, and tag managers often run synchronously during interactions, adding unpredictable delays.
- Inefficient rendering – Complex CSS selectors, large shadows, or JavaScript‑driven HTML inflates presentation delay.
Identifying which of these factors is responsible for your worst interactions is the first step toward an effective fix.
Measuring INP: Field Data vs. Lab Tools
Because INP depends on real user behavior, field data is the gold standard for decision‑making. Lab tools are useful for reproducing and debugging specific issues, but they can’t capture the variability of actual traffic.
Field Sources
- Chrome User Experience Report (CrUX) – The dataset Google uses for ranking. Accessible via PageSpeed Insights, Search Console, or the CrUX API.
- Real‑User Monitoring (RUM) – Libraries like
web-vitalslet you collect INP directly from your visitors, with attribution that tells you which element and interaction type caused the slowest latency. - PageSpeed Insights – Shows both lab and field INP; the field number comes from CrUX and reflects the last 28 days of real‑user data.
- Google Search Console – Groups URLs by INP status (Good, Needs Improvement, Poor) so you can see which page templates are problematic.
Lab Sources (for debugging)
- Chrome DevTools Performance panel – Record a session, interact with the suspect element, and inspect the Interactions track to see the breakdown of input, processing, and presentation delay.
- Long Animation Frames (LoAF) API – Available in Chrome 123+, this API provides script‑level attribution for long frames, making it easier to pinpoint the exact function or third‑party script responsible.
- Lighthouse – While Lighthouse doesn’t measure INP directly, its Total Blocking Time (TBT) metric correlates well and can highlight long‑task issues during page load.
- Web Vitals extension – Gives you real‑time INP readings in the browser as you interact.
When you have field data showing a problem, use lab tools to reproduce the interaction, identify the offending code, then verify the fix with fresh field measurements after a CrUX update (roughly 28 days).
Step‑by‑Step Optimization Checklist
Below is a practical, ordered workflow you can follow. Each step addresses one or more of the INP phases and includes code snippets where helpful.
1. Identify the Worst Interactions
- Run the
web-vitals/attributionbuild on your site for a few days or pull the latest CrUX data. - Look for the element, interaction type (click, tap, keypress), and phase that contributes most to the high INP.
- Prioritize fixes on interactions that are both slow and frequent (e.g., “Add to Cart” clicks on product pages).
2. Break Up Long Tasks
Any synchronous block longer than 50 ms stalls the main thread. Split it into smaller chunks and yield control back to the browser.
// Before: a single long task
function processItems(items) {
items.forEach(i => heavyWork(i)); // might be 300 ms
}
// After: yield every ~40 ms
async function processItemsChunked(items) {
let start = performance.now();
for (const item of items) {
heavyWork(item);
if (performance.now() - start > 40) {
await scheduler.yield() ?? new Promise(r => setTimeout(r, 0));
start = performance.now();
}
}
}
If scheduler.yield isn’t available (older browsers), the setTimeout fallback still breaks the task, though with slightly lower priority.
3. Optimize Event Handlers
Keep the handler lean: do only what’s needed for immediate visual feedback, then defer everything else.
- Show instant feedback – add a loading class, change an icon, or disable the button right away.
- Move non‑urgent work – analytics, data persistence, prefetching, or heavy computations can go into
requestIdleCallback,setTimeout, or a Web Worker. - Debounce rapid inputs – for search boxes or sliders, wait until the user pauses before executing the expensive logic.
- Use
requestAnimationFramefor visual updates that must happen before the next paint but can defer heavy JS until after that frame.
Example:
button.addEventListener('click', async () => {
// Immediate visual cue
button.classList.add('loading');
// Defer heavy work until after paint
await requestAnimationFrame(() => {
const data = computeExpensiveResult();
updateUI(data);
button.classList.remove('loading');
});
// Non‑critical analytics after a short idle window
requestIdleCallback(() => sendAnalytics('click'));
});
4. Eliminate Layout Thrashing
Batch all DOM reads, then all writes. Avoid patterns like reading offsetHeight inside a loop that also writes to style.height.
// Bad – forces layout on every iteration
elements.forEach(el => {
const h = el.offsetHeight; // read → layout
el.style.height = h + 10 + 'px'; // write
});
// Good – single layout pass
const heights = elements.map(el => el.offsetHeight); // all reads
elements.forEach((el, i) => {
el.style.height = heights[i] + 10 + 'px'; // all writes
});
5. Reduce DOM Size and Complexity
A large DOM amplifies every phase of INP.
- Aim for under 1,400 nodes on pages where interactions happen frequently (product listings, dashboards).
- Use virtualization for long lists (e.g.,
react-window,@tanstack/virtual). - Apply
content-visibility: autoto off‑screen sections so the browser skips layout and paint for hidden content. - Remove unnecessary wrappers, favor semantic HTML, and keep CSS selectors simple.
6. Manage Third‑Party Scripts
Third‑party code is a frequent INP killer because it often runs synchronously during interactions.
- Audit – list all third‑party scripts, measure their main‑thread impact via the LoAF API or DevTools.
- Defer or lazy‑load – load scripts only after the first user interaction or during idle periods using a facade pattern.
- Use Partytown – move heavy analytics or advertising scripts into a Web Worker, keeping them off the main thread.
- Replace heavy libraries – swap out bulky dependencies (Moment.js, full jQuery) for lighter alternatives (date‑fn$s, vanilla JS).
- Consent‑mode triggers – fire non‑essential tags only after the user has interacted with the page or after a short timeout.
7. Leverage Modern Scheduling APIs
The scheduler.yield() API is purpose‑built for yielding while preserving task priority. Pair it with a fallback for broader browser support.
function yieldToMain() {
if (globalThis.scheduler?.yield) {
return scheduler.yield();
}
return new Promise(resolve => setTimeout(resolve, 0));
}
Use it inside long loops, recursive functions, or any place where you need to let the browser process pending interactions.
8. Framework‑Specific Tweaks
If you’re using a modern framework, take advantage of its built‑in performance primitives.
- React –
useTransitionanduseDeferredValuefor non‑urgent updates;React.memoto prevent unnecessary re‑renders; virtualized lists for large data sets. - Vue –
v-memofor expensive lists,defineAsyncComponentfor code‑splitting, andcomputedfor caching expensive values. - Angular –
OnPushchange detection,trackByforngFor, and virtual scrolling via the CDK. - Svelte – minimal runtime overhead already helps; still watch for reactive statements that cause excessive updates.
9. Validate with Real‑User Data
After deploying changes:
- Keep the
web-vitalsRUM beacon active for at least a week. - Compare the new 75th‑percentile INP against the baseline.
- Check Search Console after the next CrUX update (≈ 28 days) to see if the URL group’s status improved.
- Set up alerts for regressions so future feature additions don’t accidentally reintroduce long tasks.
Tools to Help You Along the Way
| Tool | What it’s best for |
|---|---|
| PageSpeed Insights | Quick field INP check via CrUX; also shows lab TBT for correlation. |
| Google Search Console | Identify which URL groups are failing and track trends over time. |
| web-vitals library (with attribution) | Collect real‑user INP and see which element/interaction caused it. |
| Chrome DevTools → Performance panel | Record interactions, view the Interactions track, and inspect long tasks or LoAF entries. |
| Long Animation Frames API | Script‑level attribution for slow interactions (Chrome 123+). |
| Lighthouse | Lab TBT as a proxy for long‑task detection during page load. |
| WebPageTest | Cross‑device lab testing; can simulate throttled mobile conditions. |
Scheduler polyfill (scheduler-polyfill) | Enables scheduler.yield()‑like behavior in older browsers. |
Prioritize tools that give you field data first; use lab tools for deep dives and verification.
Prioritizing Your Efforts
Not all interactions deserve equal attention. Focus on:
- High‑traffic, high‑value paths – product pages, checkout flows, sign‑up forms.
- Interactions with the worst latency – those contributing most to the 75th‑percentile INP.
- Frequent, repetitive actions – typing in a search box, opening a navigation menu, toggling a filter.
By fixing the slowest, most common interactions first, you’ll see the biggest impact on both field INP and user satisfaction.
Frequently Asked Questions
Q: My FID was good, but INP is poor. Why? FID measured only the delay before the first interaction began. It ignored processing time, presentation delay, and all later interactions. INP captures the full response chain, so a page can look fast to start but feel sluggish once scripts start running or the DOM grows large.
Q: Can I rely on lab tools alone to fix INP? Lab tools are excellent for reproducing a specific problem and testing a fix, but they don’t reflect the variability of real users. Always validate changes with field data (CrUX or RUM) before considering the work complete.
Q: How long does it take for INP improvements to appear in Search Console? CrUX data is a rolling 28‑day average. Expect to see shifts after roughly two weeks, with the full effect visible after a full cycle. Use PageSpeed Insights’ lab data for immediate feedback while you wait.
Q: Is INP only a mobile problem? Mobile devices often show worse INP due to slower CPUs and touch latency, but desktop interactions can also be slow if the main thread is blocked. Optimize for both, but give mobile extra attention because it usually drives the worst scores.
Q: Does improving INP hurt other Core Web Vitals? Generally, the techniques that help INP (breaking up long tasks, reducing DOM size, deferring third‑party scripts) are neutral or beneficial for LCP and CLS. Watch out for aggressive lazy‑loading that might cause layout shifts, but those can be mitigated with proper placeholders.
Conclusion
Interaction to Next Paint is the metric that tells Google—and your users—how responsive your site truly feels after the initial load. By measuring the full latency of every click, tap, or key press, INP exposes the hidden delays that frustrate visitors and hurt rankings. The good news is that the causes are well understood: long JavaScript tasks, heavy event handlers, layout thrashing, bloated DOMs, and unchecked third‑party scripts.
Fixing INP isn’t about a single silver bullet; it’s a series of targeted, incremental improvements. Break up long work with scheduler.yield(), keep event handlers light and defer non‑essential tasks, eliminate layout thrashing, shrink the DOM, and manage third‑party impact with facades, workers, or smart loading strategies. Validate each change with real‑user data, and keep an eye on regressions as your site evolves.
When you consistently keep the 75th‑percentile INP at or below 200 ms, you’ll not only satisfy Google’s Core Web Vitals requirement—you’ll deliver a snappy, trustworthy experience that keeps users engaged, lowers bounce rates, and ultimately supports your business goals. Start with the worst interaction you can find, apply the techniques above, and watch your INP—and your site’s performance—move in the right direction.
