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
  • 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');
  • 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;
      }
      

🖼️ 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. Ensure srcset and sizes 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 have defer or async?
    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 or br.
    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.