If you've ever opened a page from your site in Google Search Console, you've likely come across the Core Web Vitals report. This set of metrics, which Google has made the primary measure of user experience in search results, has become a puzzle for many site owners: what exactly does each one measure? Where is the passing threshold? And most importantly, where should you start improving?
In this article, instead of generic explanations, we dive into the technical details. We'll see what browser behavior each Core Web Vitals metric measures, how the number you see in the report is calculated, and with real-world examples and practical commands, you'll learn how to diagnose and fix the problem. If your site has high traffic or runs on a weak shared server, this guide is exactly for you.
What are Core Web Vitals and why should you care?
Core Web Vitals are three key metrics that Google has defined to measure the quality of user experience on the web. These metrics have been used as a ranking signal in search results since 2021, and in 2024, the FID metric was replaced by INP. But the important point is that these metrics aren't just for SEO; they are directly related to your conversion rate, user engagement time, and revenue.
The three main metrics are:
- LCP (Largest Contentful Paint) — measures the loading time of the largest content element on the page (usually an image, video, or large text block).
- INP (Interaction to Next Paint) — evaluates the page's responsiveness to user interactions (click, typing, scroll) throughout the entire visit.
- CLS (Cumulative Layout Shift) — measures the amount of unexpected movement of page elements during loading.
The passing thresholds for each metric are as follows:
- LCP: less than 2.5 seconds (poor: more than 4 seconds)
- INP: less than 200 milliseconds (poor: more than 500 milliseconds)
- CLS: less than 0.1 (poor: more than 0.25)
Important note: Google uses Field Data for the Search Console report, which is collected from real users' browsers. Therefore, improving only in a test environment isn't enough; you need to improve the real user experience.
The LCP Metric: How fast does the largest page element load?
LCP measures the moment when the largest content element (image, video, text block) is rendered in the user's viewport. This metric is typically influenced by three main factors: server response speed (TTFB), loading time of critical resources, and client-side rendering time.
How to diagnose LCP?
The first step is to identify the LCP element. In Chrome DevTools, open the Performance tab and record a session. In the Timings section, the largest element is identified. You can also use the following command in the console:
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(entry.element, entry.startTime);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
After identifying the LCP element, follow these steps in order of priority:
- Improve TTFB: If the server response time is above 600 milliseconds, the problem is with the server. Consider using a CDN, enabling HTTP/2 and HTTP/3, and optimizing database queries.
- Load the LCP image: If the LCP element is an image, serve it in WebP or AVIF format and use
fetchpriority="high":
<img src="hero.webp" fetchpriority="high" width="1200" height="630" alt="image description">
- Remove render-blocking JavaScript: Load scripts that execute before the LCP element renders with
deferorasync. - Preconnect to critical resources: Use
<link rel="preconnect">for domains that serve fonts or APIs.
Common mistake: Many developers only optimize the LCP image but forget that web fonts can also delay text rendering. If your LCP element is a text heading, use font-display: swap and load the font file with preload.
The INP Metric: Page responsiveness to user interactions
INP replaces FID and is a more accurate metric: instead of measuring only the first interaction, it examines all user interactions during the visit and reports the worst (or near-worst) value. This metric is directly dependent on the main thread's lifespan.
Why is your INP poor?
The main reasons for high INP include:
- Heavy JavaScript that blocks the main thread for long periods
- Complex event listeners that take time to process
- Frequent DOM renders that cause Layout Thrashing
- Third-party scripts (ads, chat widgets, analytics) that run on the main thread
Practical solutions for improving INP
The first step is to measure the longest tasks. In DevTools, open the Performance tab and examine the Main section. Tasks that take more than 50 milliseconds are problematic.
Then apply these techniques:
- Code Splitting: Split JavaScript into multiple small bundles and load only the code needed for the current page. With Webpack or Vite, you can use dynamic
import(). - Defer non-essential work: Use
requestIdleCallbackto run low-priority tasks during browser idle time:
if ('requestIdleCallback' in window) {
requestIdleCallback(() => {
// Load non-essential widgets
loadChatWidget();
}, { timeout: 2000 });
}
- Reduce third-party work: Load advertising and analytics scripts with
deferand useIntersectionObserverto load them only when the user scrolls to that section. - Optimize DOM: Reduce the number of DOM nodes. Pages with more than 1500 nodes render significantly slower.
Common mistake: Using heavy UI libraries like jQuery for simple tasks. If you're using jQuery just for a button or dropdown menu, replace it with vanilla JavaScript. This can improve INP by up to 30%.
The CLS Metric: Visual stability of the page
CLS measures the total score of unexpected element movements during the page's lifetime. Each time an element moves after the initial render, a negative score is recorded. This typically happens due to late loading of images, fonts, or ads.
Main sources of high CLS
- Images and videos without specified dimensions (width and height)
- Web fonts loaded with FOIT/FOUT
- Ads or widgets inserted after the initial render
- CSS animations that change layout properties
Practical solutions for zero CLS
Follow this checklist in order:
- Explicit dimensions for all media: Specify
widthandheightattributes for every image and video. Even if CSS makes them responsive, write the original dimensions in the HTML:
<img src="banner.jpg" width="800" height="450" style="width:100%; height:auto;" alt="banner">
- Reserve space for ads: If you insert ads after the page loads, place a container with specified dimensions in the HTML beforehand:
<div class="ad-slot" style="min-height: 250px; width: 100%;"></div>
- Use font-display: swap: This property causes text to first display with a system font and then be replaced once the web font loads. To prevent shifting, you can use
size-adjustin@font-face. - Safe animations: Only use
transformandopacityproperties for animations, notwidth,height, ortop.
Common mistake: Using skeleton loaders for dynamic content. If the skeleton's height differs from the final content, it creates worse CLS. It's better to estimate the exact content height in advance.
Tools for measuring and monitoring Core Web Vitals
For effective improvement, you need continuous measurement. Use these tools in combination:
- PageSpeed Insights: Shows a combination of field data (CrUX) and lab data (Lighthouse).
- Chrome DevTools: For deep debugging and identifying the LCP element and long tasks.
- web-vitals JavaScript library: For Real User Monitoring (RUM) on your own site:
import {onLCP, onINP, onCLS} from 'web-vitals';
onLCP((metric) => {
console.log('LCP:', metric.value);
// Send to analytics
});
onINP((metric) => console.log('INP:', metric.value));
onCLS((metric) => console.log('CLS:', metric.value));
- CrUX API: For viewing historical data and comparing with competitors.
Step-by-step improvement strategy for high-traffic sites
If your site has high traffic, don't apply changes all at once. This carries the risk that a small mistake could ruin the user experience for thousands of people. Instead, follow this strategy:
- Week one — Measure and identify: Review CrUX data for the past 28 days. Prioritize pages that are in the poor threshold.
- Week two — Fix infrastructure issues: Check TTFB, server-side caching, and CDN. If the site is on a shared server, consider upgrading to a dedicated plan or VPS. (In this regard, ServerNet offers various options for high-traffic hosting.)
- Week three — Optimize assets: Convert images to WebP, subset fonts, and minify CSS/JS.
- Week four — Optimize JavaScript: Remove or defer third-party code and implement code splitting.
- Continuous monitoring: After each change, review CrUX data for 7 days. Improvements are usually reflected in Google's report after 28 days.
Conclusion
Core Web Vitals aren't just an SEO metric; they're a reflection of your site's technical quality. By improving LCP, INP, and CLS, you'll not only get a better ranking on Google, but you'll also see reduced bounce rates and increased conversions. Use this guide as a roadmap: first measure, then diagnose, and finally apply improvements with small, measurable changes. Remember that optimization is an ongoing process, not a one-time project.
Comments 0
No comments yet — be the first!