Core Web Vitals are Google's metrics for measuring user experience. This guide shows you exactly how to optimize each metric for better rankings.
Understanding Core Web Vitals
- LCP (Largest Contentful Paint): Loading performance - target under 2.5 seconds
- FID (First Input Delay): Interactivity - target under 100 milliseconds
- CLS (Cumulative Layout Shift): Visual stability - target under 0.1
Optimizing LCP (Largest Contentful Paint)
1. Optimize Largest Element
// Identify LCP element
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP element:', lastEntry.element);
console.log('LCP time:', lastEntry.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });
2. Optimize Images
<!-- Use modern formats -->
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="Description" loading="eager">
</picture>
<!-- Preload critical images -->
<link rel="preload" as="image" href="hero-image.webp">
<!-- Set width/height to prevent layout shift -->
<img src="image.jpg" width="1200" height="630" ...>
3. Optimize Server Response Time
// Implement caching
Cache-Control: public, max-age=31536000, immutable
// Use CDN
// Optimize database queries
// Upgrade hosting
Optimizing FID (First Input Delay)
1. Reduce JavaScript Execution Time
// Code splitting
import('heavy-library.js').then(module => {
module.init();
});
// Remove unused code
// Use Webpack Bundle Analyzer
// Defer non-critical JavaScript
<script defer src="non-critical.js"></script>
2. Use Web Workers for Heavy Tasks
// main.js
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = (e) => {
console.log('Result:', e.data);
};
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data);
self.postMessage(result);
};
Optimizing CLS (Cumulative Layout Shift)
1. Set Dimensions on Media
<!-- Always set width and height -->
<img src="image.jpg" width="800" height="600" loading="lazy">
<video width="640" height="360" controls>...</video>
<!-- Or use aspect-ratio CSS -->
<style>
.image-container {
aspect-ratio: 16 / 9;
background: #f0f0f0;
}
img {
width: 100%;
height: auto;
}
</style>
2. Reserve Space for Dynamic Content
<!-- Reserve space for ads -->
<div class="ad-container" style="min-height: 250px;">
<!-- Ad loads here -->
</div>
<!-- Reserve space for fonts -->
<style>
@font-face {
font-family: 'CustomFont';
src: url('font.woff2');
font-display: swap; /* Show fallback font while loading */
}
</style>
Testing and Monitoring Tools
- PageSpeed Insights: Lab and field data
- Search Console: Core Web Vitals report
- Chrome UX Report (CrUX): Real user data
- Web Vitals JS library: Measure in your app
Quick Wins Checklist
□ Optimize largest image/hero section (LCP) □ Implement image lazy loading □ Add width/height to all images (CLS) □ Minimize main thread work (FID) □ Use font-display: swap (CLS) □ Implement caching headers □ Reduce unused CSS/JS □ Enable compression (gzip/brotli) □ Use a CDN □ Optimize database queriesConclusion
Good Core Web Vitals improve both user experience and SEO rankings. Start by measuring current performance, then tackle the most impactful issues first.

