Core Web Vitals 2026: A Complete Guide to INP Optimization and Performance Gains in Practice
In March 2024, Google officially replaced FID with INP as a core performance metric. INP is currently the hardest Core Web Vitals metric to optimize, and this article lays out a systematic approach to improving it.
1. Core Web Vitals Standards in 2026
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| LCP | < 2.5s | 2.5-4s | > 4s |
| INP | < 200ms | 200-500ms | > 500ms |
| CLS | < 0.1 | 0.1-0.25 | > 0.25 |
2. INP Optimization in Depth
What Is INP
INP (Interaction to Next Paint) measures the time from a user interaction (click, key press, etc.) to the browser rendering the next frame.
It evaluates the 75th percentile latency across all interactions throughout the entire page lifecycle, making it more comprehensive than FID.
The Three Phases of INP
User input → [Input delay] → Event processing → [Processing time] → Rendering → [Presentation delay] → Visual update
Input delay: The main thread is busy and cannot respond to input immediately Processing time: The time spent running the event handlers Presentation delay: The time the browser needs to render the update
INP Optimization Strategies
1. Reduce Input Delay
A blocked main thread is the primary culprit:
Break up long tasks:
// Bad: a single long task that blocks the main thread
function processLargeData(data) {
data.forEach(item => {
// Complex computation...
});
}
// Optimized: chunk the work using scheduler.postTask or setTimeout
async function processLargeDataOptimized(data) {
const chunks = chunkArray(data, 50);
for (const chunk of chunks) {
await scheduler.postTask(() => {
chunk.forEach(item => { /* computation */ });
}, { priority: "background" });
}
}
Reduce the impact of third-party scripts:
- Audit every third-party script (analytics tools, ads, chat widgets)
- Load non-critical scripts with async/defer
- Consider deferring third-party script loading until after a user interaction
2. Optimize Event Processing Time
Avoid running expensive operations inside event handlers:
// Problem: heavy DOM operations on click
button.addEventListener("click", () => {
// Large amount of synchronous DOM work
updateHundredsOfElements();
});
// Optimized: use requestAnimationFrame
button.addEventListener("click", () => {
requestAnimationFrame(() => {
updateHundredsOfElements();
});
});
Framework optimizations for React/Vue:
- Use React.memo to prevent unnecessary re-renders
- Use useDeferredValue to defer low-priority updates
- Use a Virtual List to handle large data sets
3. Reduce Presentation Delay
- Avoid forced synchronous layout (writing to the DOM immediately after reading from it)
- Use the CSS contain property to limit the scope of layout impact
- Reduce the complexity of CSS selectors
3. Advanced LCP Optimization
Identifying the LCP Element
// Use Performance Observer to identify the LCP element
const observer = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
console.log("LCP element:", lastEntry.element);
console.log("LCP time:", lastEntry.startTime);
});
observer.observe({type: "largest-contentful-paint", buffered: true});
Optimizing Image LCP
<!-- Make sure the LCP image is not lazy-loaded, and give it a fetchpriority hint -->
<img
src="hero-image.webp"
alt="Hero image"
fetchpriority="high"
decoding="async"
width="1200" height="630"
>
<!-- Preconnect to critical third-party domains -->
<link rel="preconnect" href="https://cdn.sgaindex.com">
<link rel="preload" href="/hero-image.webp" as="image">
4. CLS Optimization in Practice
Common Sources of CLS and Their Fixes
Images without dimension attributes:
<!-- Wrong: no dimensions, causing layout shift while loading -->
<img src="article-image.jpg" alt="Article image">
<!-- Right: specify width and height -->
<img src="article-image.jpg" alt="Article image" width="800" height="450">
Dynamically injected content:
/* Reserve space for ads / dynamic content */
.ad-container {
min-height: 250px;
aspect-ratio: 728 / 90;
}
Font flashing (FOIT/FOUT):
@font-face {
font-family: "CustomFont";
font-display: optional; /* If the font hasn't loaded, just use the system font */
}
5. Core Web Vitals Monitoring Tools
| Tool | Data Type | Use Case |
|---|---|---|
| PageSpeed Insights | Lab + field data | Single-page diagnostics |
| Chrome DevTools | Lab data | Development and debugging |
| GSC Core Web Vitals report | Real-user data | Site-wide monitoring |
| Lighthouse CI | Lab data | CI/CD integration |
| web-vitals.js | Real-user data | Custom monitoring |
Conclusion
Optimizing Core Web Vitals is an ongoing process, not a one-time fix. We recommend setting up performance regression testing within your CI/CD pipeline to ensure that each code change does not introduce new performance issues. INP optimization requires deep collaboration from front-end developers, and the SEO team should establish a regular communication channel with the development team.