Core Web Vitals: The 2026 Guide to Better LCP, INP, and CLS
If you want to improve the performance of a website, the first question is always the same: What exactly should we measure?
Core Web Vitals answer that question with three metrics focused on loading, stability, and responsiveness. These metrics (Largest Contentful Paint, Cumulative Layout Shift, and Interaction to Next Paint) represent Google’s framework for quantifying user experience. They directly influence search rankings, user satisfaction, conversion rates, and ultimately, your bottom line.
As of 2026, the landscape has evolved significantly. INP has fully replaced First Input Delay (FID) as the responsiveness metric, and Core Web Vitals are now assessed holistically at the site-wide level rather than per page. Slow pages anywhere on your site can suppress rankings for every page, making optimization more critical than ever.
In this guide, we walk through each metric, explore what is actually happening inside the browser, examine common pitfalls, and provide actionable strategies to achieve and maintain passing scores.
Understanding Core Web Vitals
Core Web Vitals focus on three aspects of user experience:
- Largest Contentful Paint (LCP) — measures how quickly the main content appears (loading).
- Cumulative Layout Shift (CLS) — measures how stable the page layout is (visual stability).
- Interaction to Next Paint (INP) — measures how responsive the page feels when users interact with it (responsiveness).
For a page to pass Core Web Vitals, all three metrics must be in the “good” range for at least 75% of visits. A single weak metric can cause a page to fail entirely, even if the other two are excellent.
Largest Contentful Paint (LCP) — Loading Performance
What Is LCP?
LCP measures the time it takes for the largest visible element in the viewport to finish rendering. Usually, this element is something like a hero image, a large heading, or the main content block.
Instead of asking “when did the page start loading?”, LCP asks a more meaningful question: “When does the main content actually appear for the user?”
How the Browser Calculates LCP
As the page loads, different elements start appearing inside the viewport:
A small element appears: the browser treats it as the current LCP candidate.
A larger element appears: the browser updates the candidate.
The largest element appears: once rendering finishes, the browser records the LCP time.
LCP is essentially the moment when the largest visible element finished painting in the viewport.
LCP Thresholds (2026)
| Category | LCP Time | Status |
|---|---|---|
| Good | ≤ 2.5 seconds | Passing |
| Needs Improvement | 2.6–4.0 seconds | Warning |
| Poor | > 4.0 seconds | Failing |
At least 75% of page loads must meet the “good” threshold based on real-world (field) data from the Chrome User Experience Report (CrUX).
The Four Sub-parts of LCP
Understanding LCP breakdown helps pinpoint exactly where optimization efforts should focus.
| Sub-part | What It Measures | Typical Target |
|---|---|---|
| Time to First Byte (TTFB) | Time from page load start to receiving the first byte of HTML | ≤ 200ms |
| Resource Load Delay | Time from TTFB to when browser starts loading the LCP resource | Minimize |
| Resource Load Duration | Time to fully load the LCP resource | Depends on file size |
| Element Render Delay | Time from resource load completion to full rendering of LCP element | Minimize |
Ideally, most LCP time should be spent on loading resources, not on delays caused by render-blocking scripts or slow server responses.
Common LCP Pitfalls
Render-Blocking JavaScript
The Problem: A slow JavaScript file is loaded in the <head>. Because scripts can modify the DOM, the browser must stop parsing HTML while the script downloads and executes. The browser cannot reach the part of the HTML where the hero image appears, so the image request starts only after the script finishes. LCP becomes significantly worse.
The Solution: Use defer on scripts that do not need to run immediately. This allows the browser to continue parsing HTML, build the DOM, and download scripts in parallel. The script executes only after HTML parsing is finished.
<script src="https://webkeepy.com/js/bundle.js" defer></script>Missing Preload Hints
The Problem: The browser discovers the LCP element too late in the HTML, so resource loading begins later than necessary.
The Solution: Preload the hero image with <link rel="preload"> in the <head> and set fetchpriority="high".
<link rel="preload" as="image" href="https://webkeepy.com/hero.avif" fetchpriority="high">Uncompressed Images
The Problem: Large image files take too long to download (for example, a 2.4 MB hero image).
The Solution: Convert images to WebP or AVIF (30–50% smaller than JPEG), use responsive srcset with breakpoints, and apply loading="eager" and fetchpriority="high" to the LCP element.
LCP Optimization Checklist
- Ensure TTFB is under 200ms.
- Use static generation (SSG) where possible; pre-rendered HTML beats any server-side solution.
- Implement CDN caching with
stale-while-revalidateheaders. - Eliminate render-blocking resources (use
deferorasync). - Preload the LCP element.
- Use modern image formats (AVIF, WebP).
- Set appropriate dimensions and
fetchpriority. - Ensure the LCP resource is discoverable from the HTML source.
An e-commerce client reduced LCP from 4.8 seconds to 1.9 seconds by switching from PNG to AVIF, preloading the hero image, moving to static generation, and using fetchpriority="high". Organic traffic increased by 23% within eight weeks.
Cumulative Layout Shift (CLS) — Visual Stability
What Is CLS?
CLS measures how much visible content moves unexpectedly while the page is loading. You have probably experienced this: you start reading something on a page, and suddenly the text jumps because an image loads above it or an advertisement suddenly appears. Each of those moments creates a layout shift. CLS adds up all these shifts into a single score.
How the Browser Calculates CLS
Imagine a simple grid layout with several elements:
Everything looks stable initially.
One element suddenly grows (for example, because an image loads and its size was not known).
Surrounding elements move to make space. This movement creates a layout shift.
Each shift moment contributes to the CLS score.
CLS Thresholds
| Category | CLS Score | Status |
|---|---|---|
| Good | ≤ 0.1 | Passing |
| Needs Improvement | 0.1–0.25 | Warning |
| Poor | > 0.25 | Failing |
Unlike LCP and INP, CLS is not measured in seconds or milliseconds; it is a unitless score based on how much content shifts and by how far.
Lab Data vs. Field Data for CLS
A common misconception is that lab tools (Lighthouse) and field data (CrUX) should show identical CLS scores. They often do not, and that is expected.
- Lab tools (Lighthouse) typically measure only the initial page load.
- CrUX (field data) measures CLS throughout the full lifecycle of the page.
- Layout shifts can happen after initial load (for example, lazy-loaded content shifting as users scroll).
- Shifts occurring within 500ms of a user interaction are excluded from CLS (considered expected shifts).
If PageSpeed Insights shows a difference between CrUX CLS and Lighthouse CLS, the discrepancy is likely due to post-load CLS issues (such as shifts that happen after scrolling).
Common CLS Pitfalls
Images Without Dimensions
The Problem: Images do not specify width and height attributes. The browser does not know how much space the image will occupy, so it reserves no space. When images finally load, the browser suddenly inserts them into the layout, and the rest of the page shifts downward.
The Solution: Always add width and height attributes to image elements. The browser can calculate the correct aspect ratio and reserve space immediately. Even before images finish loading, the layout knows how much space they need.
<img src="https://webkeepy.com/product.jpg" width="800" height="600" alt="Product">Dynamic Content Injection
The Problem: Ads, banners, or pop-ups are inserted above existing content, causing everything below to shift down unexpectedly.
The Solution: Reserve space for ads, embeds, and iframes before they load. Never insert content above content that has already rendered. Avoid injecting dynamic content (banners, pop-ups) at the top of the page after main content loads.
Web Fonts (FOUT/FOIT)
The Problem: Text reflows when web fonts load or fail to load. Invisible text (FOIT) or swapped text (FOUT) causes layout shifts.
The Solution: Use font-display: swap so text paints immediately. Consider using size-adjust to reduce Flash of Unstyled Text (FOUT).
CLS Optimization Checklist
- Add
widthandheightattributes to all images and videos. - Use CSS
aspect-ratiofor dynamic media. - Reserve space for ads, embeds, and iframes before they load.
- Never inject content above already-rendered content.
- Use
font-display: swapfor web fonts. - Avoid inserting dynamic banners or pop-ups at the top of the page.
Interaction to Next Paint (INP) — Responsiveness
What Is INP?
INP measures how quickly the page responds to user input (clicks, key presses, or taps on the screen). When a user interacts with your page, the browser should update the interface quickly so the user feels the action was recognized.
INP is the time between the user interaction and the next visual update on the screen.
Why INP Replaced FID
| Metric | What It Measured | Limitation |
|---|---|---|
| FID (First Input Delay) | Only the first interaction | Failed to capture slow interactions that occurred later in the session |
| INP (Interaction to Next Paint) | The worst interaction during the entire page visit | Captures the full user experience more accurately |
If a user clicks a button after 30 seconds and the main thread is blocked by a heavy JavaScript bundle, FID would not catch it, but INP would, because it measures the worst interaction, not just the first one.
How INP Is Calculated
INP has three sub-parts:
| Sub-part | Description |
|---|---|
| Input Delay | From user interaction start to when the event callback begins running |
| Processing Duration | Time for the event callback to complete |
| Presentation Delay | Time from callback completion to the next paint (visual update) |
INP Thresholds
| Category | INP Time | Status |
|---|---|---|
| Good | ≤ 200 milliseconds | Passing |
| Needs Improvement | 200–500ms | Warning |
| Poor | > 500ms | Failing |
Common INP Pitfalls
Heavy Processing on the Main Thread
The Problem: A button triggers heavy work. Because JavaScript is single-threaded in the browser, this work blocks everything else. The browser cannot update the UI and cannot respond to other interactions. The user clicks and nothing appears to happen until the computation finishes. Only then does the page update. The result is a slow and unresponsive experience (poor INP).
The Solution: Instead of doing all the work at once, break the task into smaller chunks. When the button is clicked, immediately update the UI to show something like “processing”. Process a small portion of the work, then yield control back to the browser. This can be done using techniques like setTimeout or chunked loops. Because you periodically yield control, the browser can repaint the UI and respond to other interactions. Users see immediate feedback, and the page remains responsive.
// Example: chunked processing
function processChunk(data, index, chunkSize) {
const chunk = data.slice(index, index + chunkSize);
// process chunk
if (index + chunkSize < data.length) {
setTimeout(() => processChunk(data, index + chunkSize, chunkSize), 0);
}
}Long Tasks (over 50ms)
The Problem: Any task that runs for more than 50ms on the main thread is a “long task”. Long tasks block the browser from handling user interactions and updating the UI.
The Solution: Break long tasks using scheduler.yield() or requestIdleCallback. Use setTimeout to split work into smaller chunks.
Heavy JavaScript Bundles
The Problem: Loading too much JavaScript on the initial page load. A single slow third-party script can push an otherwise clean site into “needs improvement” territory.
The Solution: Use code splitting to load only the JavaScript needed for the current page. Defer or delay non-critical third-party scripts (analytics, ads, chat widgets). Push non-urgent work into Web Workers when possible.
Inefficient Event Handlers
The Problem: Expensive event handlers running on every interaction.
The Solution: Debounce expensive event handlers. Use useTransition for non-urgent state updates in React. Push non-urgent work to the background.
INP Optimization Checklist
- Break long tasks (> 50ms) using
scheduler.yield()or chunked processing. - Implement code splitting to reduce initial JavaScript payload.
- Defer or delay non-critical third-party scripts.
- Debounce expensive event handlers.
- Use
requestIdleCallbackfor non-urgent work. - Move heavy processing to Web Workers where possible.
Measuring Core Web Vitals
Lab Data vs. Field Data
| Type | Tools | What It Measures | Best For |
|---|---|---|---|
| Lab Data | PageSpeed Insights, Lighthouse, WebPageTest | Simulated page loads in controlled conditions | Diagnosing issues and testing fixes |
| Field Data (RUM) | CrUX (Chrome User Experience Report), Search Console | Actual user experiences | Understanding real-world performance (what Google uses for ranking) |
Field data, not lab tools, is what Google uses to judge real-world experience. Always prioritize field data when evaluating Core Web Vitals.
Recommended Tools
| Tool | Data Type | Best Used For |
|---|---|---|
| Google Search Console → Experience → Core Web Vitals | Field data (CrUX) | Monitoring overall site health |
| PageSpeed Insights | Lab + Field (CrUX) | Detailed breakdown of scores and opportunities |
| Chrome DevTools → Performance panel | Lab data | Local testing with live metrics |
| Web Vitals Library (JavaScript) | Field data (RUM) | Measuring real user experience programmatically |
The State of Core Web Vitals in 2026
Current Thresholds (Unchanged)
| Metric | Good Threshold | 2026 Status |
|---|---|---|
| LCP | ≤ 2.5 seconds | Threshold unchanged |
| CLS | ≤ 0.1 | Threshold unchanged |
| INP | ≤ 200 milliseconds | Replaced FID in 2024; measurement methodology refined in 2026 |
The Harsh Reality
- Only 55.9% of tracked origins pass all three Core Web Vitals simultaneously.
- Individual pass rates are higher: LCP ~68.6%, CLS ~81.3%, INP ~86.6%.
- Most sites fail because of one weak metric dragging down two strong ones.
2026 Measurement Changes
- INP Methodology Refined: Better captures sustained interaction latency on input-heavy pages.
- Site-Wide Assessment: Core Web Vitals are now evaluated at the site level; slow pages anywhere can suppress rankings for every page.
- At Least 75% of Visits: Passing requires 75% of page loads to meet thresholds in field data.
The Core Principles
Improving Core Web Vitals is really about a few simple ideas:
- Prioritize important resources. Make sure the most important content appears as early as possible. Preload critical resources. Do not let JavaScript block the browser from loading important elements.
- Keep the layout predictable. Reserve space for images and dynamic content. Always specify dimensions for media. Do not inject content above already-rendered content.
- Keep the main thread free. Avoid long blocking work on the main thread. Break heavy tasks into smaller chunks. Defer non-critical scripts.
- Measure with field data. What matters is real user experience, not just lab tests. Use CrUX and Search Console to monitor your actual scores.
Final Takeaways
| Metric | What It Measures | Key Action |
|---|---|---|
| LCP | Loading speed | Eliminate render-blocking resources; preload critical images; optimize server response |
| CLS | Visual stability | Reserve space for all dynamic content; specify dimensions on images |
| INP | Responsiveness | Break long tasks; optimize event handlers; defer non-critical scripts |
All three vitals must pass simultaneously. One weak metric can cause your entire page to fail Core Web Vitals. Prioritize performance holistically, not just for individual metrics.
Additional Resources
- Run the demo project locally to test before and after versions.
- Check out detailed guides on preload, prefetch, and lazy loading.
- Explore front-end system design courses for deeper understanding of performance and architecture.
