0/X
⚡ Core Web Vitals Metrics
-
Check Largest Contentful Paint (LCP)
Why: LCP measures how fast the main content appears. A slow LCP makes the page feel heavy.
How to check: Open Chrome DevTools → Lighthouse → Generate report. Look at the LCP value (should be ≤2.5 s).
How to implement:- Preload key images:
<link rel="preload" href="/images/hero.jpg" as="image">
- Compress images: Use Squoosh or ImageMagick to reduce file size.
- Serve next-gen formats: Convert JPEG/PNG to WebP:
cwebp input.png -o output.webp
- Preload key images:
-
Check Total Blocking Time (TBT) as proxy for FID
Why: TBT shows how long the main thread is blocked. Lower TBT helps pages respond faster to clicks.
How to check: Run Lighthouse in DevTools. See “Total Blocking Time” (should be ≤200 ms).
How to implement:- Defer non-critical scripts:
<script src="analytics.js" defer></script>
- Split large JS bundles:
import('./heavy-module.js').then(module => { /* … */ });
- Run long tasks off the main thread:
const worker = new Worker('worker.js');
- Defer non-critical scripts:
-
Check Cumulative Layout Shift (CLS)
Why: CLS measures visual stability. High CLS makes elements jump and frustrates users.
How to check: Lighthouse report → “Cumulative Layout Shift” (should be ≤0.1). Chrome DevTools → Performance → Record page load → Look for Layout Shift events.
How to implement:- Include width/height for images:
<img src="logo.png" width="200" height="100" alt="Logo">
- Reserve ad space: Add an empty
<div>
with fixed size before ad loads. - Use font-display:
@font-face { font-family: 'MyFont'; src: url('myfont.woff2') format('woff2'); font-display: swap; }
- Include width/height for images:
🖼️ Images and Media for Core Web Vitals
-
Optimize and Compress Images
Why: Large images slow down load time and LCP.
How to check: DevTools → Network → Filter “Img” → Sort by size.
How to implement:- Use Squoosh: Export at lower quality (e.g. 70 %).
- Serve WebP:
<picture> <source type="image/webp" srcset="image.webp"> <img src="image.jpg" alt="…"> </picture>
-
Use Responsive Images
Why: Users get only the size they need, saving bytes.
How to check: Inspect<img>
tags in page source. Ensuresrcset
andsizes
are present.
How to implement:<img src="small.jpg" srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w" sizes="(max-width: 600px) 400px, 800px" alt="…">
-
Lazy-Load Off-Screen Media
Why: Delay loading of images/videos not in view, improving initial load.
How to check: DevTools → Network → Scroll page → See when images load.
How to implement:<img src="photo.jpg" loading="lazy" alt="…"> <iframe src="video.html" loading="lazy"></iframe>
-
Serve AVIF Images
Why: AVIF often compresses better than WebP or JPEG, giving smaller files and faster LCP.
How to check: DevTools → Network → Filter “Img” → Compare file sizes of.avif
vs.webp
/.jpg
.
How to implement:<picture> <source type="image/avif" srcset="hero.avif"> <source type="image/webp" srcset="hero.webp"> <img src="hero.jpg" alt="Hero image"> </picture>
🎨 CSS Optimization for Core Web Vitals
-
Minify CSS
Why: Smaller CSS files download faster.
How to check: DevTools → Network → Filter “CSS” → Check file sizes.
How to implement: Use cssnano in your build pipeline:postcss([ require('cssnano') ]).process(css).then(result => { … });
-
Remove Unused CSS
Why: Extra CSS wastes bytes.
How to check: DevTools → Coverage tab → Reload → See unused CSS %.
How to implement: Use PurgeCSS:purgecss({ content: ['./src/**/*.html', './src/**/*.js'], css: ['./src/styles.css'] });
-
Inline Critical CSS
Why: Inlines above-the-fold styles to speed up first paint.
How to check: Lighthouse → “Eliminate render-blocking resources”.
How to implement: Extract critical CSS (manual or with Critical CLI):npx critical index.html --inline --minify
🚀 JavaScript Optimization for Core Web Vitals
-
Minify and Compress JS
Why: Smaller JS means faster parsing and download.
How to check: DevTools → Network → Sort “JS” by size.
How to implement: Use Terser:terser input.js -o output.min.js --compress --mangle
-
Defer or Async Non-Critical Scripts
Why: Prevent render blocking by heavy scripts.
How to check: View page source: do scripts havedefer
orasync
?
How to implement:<script src="widget.js" async></script> <script src="main.js" defer></script>
-
Remove Unused JS
Why: Dead code increases bundle size.
How to check: DevTools → Coverage → Identify unused code.
How to implement: Tree-shake in Webpack or Rollup by using ES modules. -
Use Passive Event Listeners
Why: Passive listeners improve scroll performance and lower input delay.
How to check: DevTools → Performance → Record → Look for non-passive “Listener” events.
How to implement:document.addEventListener('scroll', onScroll, { passive: true });
🎯 Resource Prioritisation for Core Web Vitals
-
Preload Key Resources
Why: Helps browser fetch critical files early.
How to check: Lighthouse → “Preload key requests”.
How to implement:<link rel="preload" href="fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
-
Use HTTP/2 or HTTP/3
Why: Multiplexing reduces load time.
How to check: DevTools → Network → Protocol column.
How to implement: Enable HTTP/2 in server config (e.g., Nginx:listen 443 ssl http2;
). -
Use DNS-Prefetch and Preconnect
Why: Resolves domains early, speeding up connections.
How to check: DevTools → Network → Look for late DNS lookups.
How to implement:<link rel="dns-prefetch" href="//example.com"> <link rel="preconnect" href="https://example.com" crossorigin>
🔤 Fonts for Core Web Vitals
-
Preload and Optimize Fonts
Why: Reduces font-related layout shifts and delays.
How to check: Lighthouse → “Ensure text remains visible during webfont load”.
How to implement:<link rel="preload" href="fonts/Roboto.woff2" as="font" type="font/woff2" crossorigin> font-display: swap;
🌐 Server and Caching for Core Web Vitals
-
Reduce Time to First Byte (TTFB)
Why: Fast TTFB improves all metrics.
How to check: DevTools → Network → “Waiting (TTFB)”.
How to implement: Use a CDN (e.g., Cloudflare) and optimize backend/database caching. -
Enable GZIP or Brotli Compression
Why: Compressed files transfer faster.
How to check: Inspect response headers →content-encoding: gzip
orbr
.
How to implement: Nginx example:gzip on; gzip_types text/css application/javascript;
-
Set Proper Cache-Control Headers
Why: Browser reuses resources on repeat visits.
How to check: Response headers →Cache-Control
.
How to implement: Example:Cache-Control: public, max-age=31536000, immutable
🤖 Third-Party Scripts for Core Web Vitals
-
Audit and Limit Third-Party Code
Why: Ads and widgets can block rendering.
How to check: DevTools → Network → Filter by third-party domains.
How to implement: Remove unused widgets and lazy-load analytics after load event.
🧩 DOM and Rendering for Core Web Vitals
-
Reduce DOM Size
Why: A large DOM slows rendering and JS execution.
How to check: DevTools → Elements → Count nodes.
How to implement: Simplify HTML and remove hidden/unused elements. -
Avoid Layout Thrashing
Why: Repeated reads/writes force extra layouts.
How to check: DevTools → Performance → Look for “Forced reflow”.
How to implement: Batch DOM reads and writes separately:// BAD element.style.width = element.offsetWidth + 'px'; // GOOD const w = element.offsetWidth; element.style.width = w + 'px';
🧰 Monitoring and Testing Tools for Core Web Vitals
-
Use Lighthouse
Why: Automated audit for Core Web Vitals.
How to check: DevTools → Lighthouse → Run.
How to implement: Integrate into CI with lighthouse-ci. -
Use PageSpeed Insights
Why: Field data plus lab data.
How to check: Go to PageSpeed Insights → Enter URL.
How to implement: Review suggestions and apply tasks above. -
Set Up Real User Monitoring (RUM)
Why: Track actual user performance over time.
How to check: Include Web Vitals library and view console logs.
How to implement:<script src="https://unpkg.com/[email protected]/dist/web-vitals.iife.js"></script> <script> webVitals.getLCP(console.log); webVitals.getFID(console.log); webVitals.getCLS(console.log); </script>
📊 Performance Budgets for Core Web Vitals
-
Define Performance Budgets
Why: Budgets set clear limits to catch regressions early.
How to check: In build/CI logs, see if bundle sizes or Lighthouse scores exceed budgets.
How to implement: Webpack config:module.exports = { performance: { maxAssetSize: 150000, maxEntrypointSize: 300000 } };
-
Enforce Budgets in CI
Why: Automating budget checks prevents bad code from merging.
How to check: CI should fail when budgets are exceeded.
How to implement: Use the bundlesize npm package:"scripts": { "bundlesize": "bundlesize" }, "bundlesize": [ { "path": "dist/*.js", "maxSize": "150 kB" } ]
🧰 Monitoring and Testing Tools for Core Web Vitals
-
Test with WebPageTest
Why: WebPageTest provides detailed waterfalls, filmstrips, and real-device metrics.
How to check: Go to webpagetest.org, enter URL, choose device and connection, run test.
How to implement: Review “First Contentful Paint”, “Speed Index”, and script regular tests via their scripting API.