Isaac.

Web Performance Metrics

Understand and optimize key web performance metrics.

By EMEPublished: February 20, 2025
web performancemetricscore web vitalsoptimization

A Simple Analogy

Web performance metrics are vital signs of your website. They show how healthy and responsive your site is to users.


Why Performance Matters?

  • User experience: Faster is better
  • Conversion: Slow sites lose customers
  • SEO: Google ranks fast sites higher
  • Accessibility: Enables users on slow connections
  • Cost: Performance affects cloud expenses

Core Web Vitals

Largest Contentful Paint (LCP)
- When largest content element loads
- Target: < 2.5 seconds
- User perceives this as page load

First Input Delay (FID)
- Delay from user input to response
- Target: < 100 milliseconds
- Measures interactivity

Cumulative Layout Shift (CLS)
- Unexpected layout changes
- Target: < 0.1
- Measures visual stability

Measuring Performance

// Measure LCP
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('LCP:', entry.renderTime || entry.loadTime);
  }
});
observer.observe({entryTypes: ['largest-contentful-paint']});

// Measure FID
const fidObserver = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('FID:', entry.processingDuration);
  }
});
fidObserver.observe({entryTypes: ['first-input']});

// Measure CLS
let clsValue = 0;
const clsObserver = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      clsValue += entry.value;
      console.log('CLS:', clsValue);
    }
  }
});
clsObserver.observe({entryTypes: ['layout-shift']});

Optimization Techniques

<!-- Defer non-critical CSS -->
<link rel="stylesheet" href="critical.css">
<link rel="preload" href="non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">

<!-- Lazy load images -->
<img src="placeholder.jpg" data-src="real.jpg" loading="lazy">

<!-- Code splitting -->
<script type="module">
  import App from './app.js';
</script>

<!-- Preload critical resources -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
// Dynamic import for code splitting
const module = await import('./heavy-module.js');

// Lazy load component
const HeavyComponent = lazy(() => import('./HeavyComponent'));

Performance Budget

{
  "bundles": [
    {
      "name": "main.js",
      "maxSize": "150kb"
    },
    {
      "name": "styles.css",
      "maxSize": "50kb"
    }
  ],
  "metrics": [
    {
      "name": "LCP",
      "maxValue": 2500
    },
    {
      "name": "FID",
      "maxValue": 100
    },
    {
      "name": "CLS",
      "maxValue": 0.1
    }
  ]
}

Lighthouse Scoring

# CLI
npm install -g lighthouse
lighthouse https://example.com --view

# CI/CD
lighthouse https://example.com --output-path=report.html --chrome-flags="--headless"

Best Practices

  1. Monitor continuously: Track metrics over time
  2. Set budgets: Define performance targets
  3. Test on real devices: Lab vs field data differs
  4. Optimize images: Use modern formats
  5. Minimize JavaScript: Only load what's needed

Related Concepts

  • Bundle analysis
  • Tree shaking
  • Server-side rendering
  • Static site generation

Summary

Monitor Core Web Vitals to understand user experience. Optimize LCP, FID, and CLS through lazy loading, code splitting, and performance budgets.