Skip to content
intermediatePhase 38 · Web Performance

Core Web Vitals

Measure LCP, INP, CLS, and understand Google's performance metrics.

45m
0 problems
Topic Progress0%

What are Core Web Vitals

What are Core Web Vitals

Core Web Vitals are a set of metrics defined by Google that measure real-world user experience on web pages.

The Three Core Web Vitals

  1. Largest Contentful Paint (LCP) - Measures loading performance
  2. Interaction to Next Paint (INP) - Measures interactivity
  3. Cumulative Layout Shift (CLS) - Measures visual stability

Why CWV Matters

  • SEO: Google uses CWV as a ranking signal
  • User Experience: Better metrics correlate with better UX
  • Business Impact: Faster sites have higher conversion rates
  • Competitive Advantage: Better performance than competitors

CWV Thresholds

Metric Good Needs Improvement Poor
LCP ≤ 2.5s ≤ 4.0s > 4.0s
INP ≤ 200ms ≤ 500ms > 500ms
CLS ≤ 0.1 ≤ 0.25 > 0.25

Measuring Tools

// Web Vitals library
import { onLCP, onINP, onCLS } from 'web-vitals';

function sendToAnalytics(metric) {
  console.log(metric);
  // Send to your analytics service
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);

Lab vs Field Data

Lab Data (Lighthouse):

  • Controlled environment
  • Consistent results
  • Good for debugging
  • Doesn't reflect real users

Field Data (CrUX):

  • Real user data
  • Varies by device/network
  • Google Search Console
  • More representative

Measuring CWV

Measuring CWV

Using web-vitals Library

// utils/web-vitals.js
import { onLCP, onINP, onCLS, onFCP, onTTFB } from 'web-vitals';

const vitals = [];

function handleVital(metric) {
  vitals.push({
    name: metric.name,
    value: metric.value,
    rating: metric.rating, // 'good', 'needs-improvement', 'poor'
    delta: metric.delta,
    id: metric.id,
    navigationType: metric.navigationType,
  });

  // Send to analytics
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/vitals', JSON.stringify({
      ...metric,
      page: window.location.pathname,
      userAgent: navigator.userAgent,
    }));
  }
}

onLCP(handleVital);
onINP(handleVital);
onCLS(handleVital);
onFCP(handleVital);
onTTFB(handleVital);

export function getVitals() {
  return vitals;
}

React Integration

// hooks/useWebVitals.js
import { useEffect } from 'react';
import { onLCP, onINP, onCLS } from 'web-vitals';

export function useWebVitals(callback) {
  useEffect(() => {
    const handleMetric = (metric) => {
      callback(metric);
    };

    onLCP(handleMetric);
    onINP(handleMetric);
    onCLS(handleMetric);

    return () => {
      // Cleanup if needed
    };
  }, [callback]);
}

// Usage
function App() {
  const handleVital = useCallback((metric) => {
    console.log(`${metric.name}: ${metric.value}`);
    analytics.track('web-vital', metric);
  }, []);

  useWebVitals(handleVital);

  return <Router />;
}

Chrome DevTools

  1. Performance Panel: Record and analyze page load
  2. Lighthouse: Automated performance audit
  3. Performance Metrics: Real-time CWV in DevTools

PageSpeed Insights

  • Comboses lab and field data
  • Shows CWV from Chrome UX Report
  • Provides optimization suggestions
  • Free API available

Lighthouse CI

# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [push]
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npm run build
      - uses: treosh/lighthouse-ci-action@v9
        with:
          urls: |
            http://localhost:3000/
            http://localhost:3000/products
          budgetPath: ./lighthouse-budget.json

Improving CWV

Improving CWV

LCP Improvements

// 1. Optimize hero image
function HeroSection() {
  return (
    <div className="hero">
      <img
        src="/hero-image.webp"
        alt="Hero"
        width="1200"
        height="600"
        fetchPriority="high"
        decoding="async"
      />
    </div>
  );
}

// 2. Preload critical resources
function Head() {
  return (
    <head>
      <link rel="preload" href="/hero-image.webp" as="image" />
      <link rel="preconnect" href="https://fonts.googleapis.com" />
      <link rel="dns-prefetch" href="https://api.example.com" />
    </head>
  );
}

INP Improvements

// 1. Break up long tasks
function processLargeDataSet(data) {
  const chunks = chunkArray(data, 100);
  
  return chunks.reduce((promise, chunk) => {
    return promise.then(() => {
      return new Promise((resolve) => {
        requestIdleCallback(() => {
          processChunk(chunk);
          resolve();
        });
      });
    });
  }, Promise.resolve());
}

// 2. Use web workers for heavy computation
const worker = new Worker('/workers/computation.js');

function useHeavyComputation(data) {
  const [result, setResult] = useState(null);
  
  useEffect(() => {
    worker.postMessage(data);
    worker.onmessage = (e) => setResult(e.data);
  }, [data]);
  
  return result;
}

CLS Improvements

// 1. Always set dimensions on images
function ResponsiveImage({ src, alt, width, height }) {
  return (
    <img
      src={src}
      alt={alt}
      width={width}
      height={height}
      style={{ aspectRatio: `${width}/${height}` }}
    />
  );
}

// 2. Reserve space for dynamic content
function AdBanner() {
  const [ad, setAd] = useState(null);
  
  return (
    <div className="ad-container" style={{ minHeight: 250 }}>
      {ad ? <AdUnit ad={ad} /> : <AdPlaceholder />}
    </div>
  );
}

// 3. Use CSS aspect-ratio
.video-container {
  aspect-ratio: 16 / 9;
  width: 100%;
}

Quick Wins Checklist

  • Enable text compression (Brotli/Gzip)
  • Serve images in modern formats (WebP/AVIF)
  • Use loading="lazy" for below-fold images
  • Preload critical resources
  • Minimize render-blocking resources
  • Use content-visibility: auto for long pages
  • Implement proper caching headers

Practice Problems

0/3solved
Build Core Web Vitals Component

Create a reusable React component implementing Core Web Vitals. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Core Web Vitals Testing

Write unit and integration tests for Core Web Vitals using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Core Web Vitals Performance

Optimize Core Web Vitals for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What are the three Core Web Vitals?

Question 1 options

2. What is a good LCP score?

Question 2 options

3. What does CLS measure?

Question 3 options

4. Why is field data more valuable than lab data?

Question 4 options

5. How can you improve INP?

Question 5 options

Flashcards

Question

What does LCP measure?

Answer

Loading performance - how quickly the largest content element becomes visible.

Question

What does INP measure?

Answer

Interactivity - the delay between user interaction and visual response.

Question

What does CLS measure?

Answer

Visual stability - unexpected layout shifts during page load.

Question

What is the web-vitals library?

Answer

A library by Google that measures Core Web Vitals in the browser.

Question

What is Core Web Vitals?

Answer

Core Web Vitals is a key concept in frontend development.

Revision Notes

Key Takeaways

  • 1.Core Web Vitals are LCP, INP, and CLS
  • 2.Good LCP is ≤ 2.5s, good INP is ≤ 200ms, good CLS is ≤ 0.1
  • 3.Use the web-vitals library to measure real user metrics
  • 4.Field data is more valuable than lab data for UX
  • 5.Quick wins include image optimization, code splitting, and reserving space

Interview Tips

  • Explain what each Core Web Vital measures
  • Discuss strategies for improving LCP, INP, and CLS
  • Know the difference between lab and field data

Cheat Sheet

Core Web Vitals Cheat Sheet

Metrics

Metric Good Poor
LCP ≤ 2.5s > 4.0s
INP ≤ 200ms > 500ms
CLS ≤ 0.1 > 0.25

Quick Fixes

  • LCP: Preload images, optimize server response
  • INP: Break long tasks, use web workers
  • CLS: Set image dimensions, reserve space

Tools

  • web-vitals library
  • Lighthouse
  • PageSpeed Insights
  • Chrome DevTools