Core Web Vitals 2026: INP Optimization Strategies That Actually Work
INP replaced FID as the core responsiveness metric. Here are battle-tested strategies to optimize Interaction to Next Paint in real-world Next.js applications.
If your site still passes Core Web Vitals on FID alone, you're living on borrowed time. Interaction to Next Paint (INP) has fully replaced First Input Delay, and it's a far more demanding metric. While FID only measured the delay before the browser started processing the first interaction, INP tracks the full round-trip — from input to the next frame painted — for every interaction during the page lifecycle.
I've spent the last six months optimizing INP across three production Next.js apps. Here's what actually moves the needle.
Understanding What INP Actually Measures
INP captures three phases: input delay, processing time, and presentation delay. Most developers fixate on processing time, but in practice, input delay — caused by long tasks blocking the main thread — is the biggest offender.
The threshold is strict: under 200ms is "good," 200–500ms "needs improvement," and above 500ms is "poor." Google uses the 75th percentile of all interactions, so a single slow handler on a frequently-used button can tank your entire score.
Strategy 1: Break Up Long Tasks with yield()
The single most impactful optimization is breaking long JavaScript tasks into smaller chunks. The scheduler.yield() API is now well-supported and should be your first tool:
async function handleFilterChange(filters: FilterState) {
// Phase 1: Update UI immediately
setActiveFilters(filters);
// Yield to let the browser paint the filter state
await scheduler.yield();
// Phase 2: Run expensive filtering
const filtered = products.filter(p => matchesFilters(p, filters));
await scheduler.yield();
// Phase 3: Update results
setFilteredProducts(filtered);
setResultCount(filtered.length);
}
By yielding between phases, the browser can paint intermediate states and respond to other interactions. This alone dropped our INP from 380ms to 140ms on a product listing page.
Strategy 2: Move Computation Off the Main Thread
For genuinely heavy computation — sorting large datasets, parsing markdown, running validations — Web Workers are the right answer. With Next.js, the setup is straightforward:
// lib/workers/sort-worker.ts
self.onmessage = (e: MessageEvent<{ items: Product[]; key: string }>) => {
const { items, key } = e.data;
const sorted = [...items].sort((a, b) => {
return String(a[key]).localeCompare(String(b[key]));
});
self.postMessage(sorted);
};
// components/ProductTable.tsx
const workerRef = useRef<Worker>();
useEffect(() => {
workerRef.current = new Worker(
new URL("../lib/workers/sort-worker.ts", import.meta.url)
);
workerRef.current.onmessage = (e) => setSortedProducts(e.data);
return () => workerRef.current?.terminate();
}, []);
const handleSort = (key: string) => {
workerRef.current?.postMessage({ items: products, key });
};
This completely removes sorting from the main thread. The interaction feels instant because the click handler returns immediately.
Strategy 3: Debounce and Throttle Strategically
Not every interaction needs immediate processing. Search inputs, resize handlers, and scroll-linked animations should be throttled. But be careful — aggressive debouncing can worsen perceived responsiveness. Use requestAnimationFrame for visual updates and reserve debounce for network calls.
Strategy 4: Audit Third-Party Scripts
Analytics, chat widgets, and A/B testing tools are INP killers. They register event listeners that run synchronously on every click. Audit with performance.measureUserAgentSpecificMemory() and the Long Animation Frames API. Consider loading non-critical scripts with requestIdleCallback or after the page becomes interactive.
Measuring INP in Production
Lab tools like Lighthouse simulate interactions but can't replicate real user behavior patterns. Use the web-vitals library to capture field data and send it to your analytics. Pay attention to the specific elements triggering poor INP — the attribution build gives you the target element and event type.
Key Takeaways
- INP measures all interactions, not just the first — optimize your most-used handlers first
scheduler.yield()is the highest-ROI optimization for most apps- Move heavy computation to Web Workers — the setup cost is minimal
- Audit third-party scripts; they're often the hidden INP bottleneck
- Measure in the field with
web-vitals— lab data doesn't capture real interaction patterns
Admin
Cal.com
Open source scheduling — tự host booking system, thay thế Calendly. Free & privacy-first.
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!