# Core Web Vitals

Google's key metrics for user experience (2024/2025 standards).

## LCP - Largest Contentful Paint

**What**: Time until largest visible element renders  
**Target**: < 2.5s  
**Poor**: > 4.0s

### Common Causes of Poor LCP
- Slow server response (TTFB)
- Render-blocking resources
- Large images/videos
- Client-side rendering delays

### Optimizations

```typescript
// Preload critical resources
<link rel="preload" href="hero.webp" as="image">

// Optimize images
<img 
  src="hero.webp" 
  srcset="hero-400.webp 400w, hero-800.webp 800w"
  sizes="(max-width: 600px) 400px, 800px"
  fetchpriority="high"
>

// Inline critical CSS
<style>/* Critical above-fold CSS */</style>
```

## INP - Interaction to Next Paint

**What**: Responsiveness to user input (replaced FID in 2024)  
**Target**: < 200ms  
**Poor**: > 500ms

### Common Causes of Poor INP
- Long JavaScript tasks
- Heavy event handlers
- Forced synchronous layouts
- Too many DOM nodes

### Optimizations

```typescript
// Break up long tasks
function processItems(items: Item[]) {
  const chunk = items.splice(0, 100);
  chunk.forEach(process);
  
  if (items.length > 0) {
    requestIdleCallback(() => processItems(items));
  }
}

// Debounce frequent handlers
let timeout: number;
input.addEventListener('input', (e) => {
  clearTimeout(timeout);
  timeout = setTimeout(() => handleInput(e), 150);
});

// Use passive event listeners
element.addEventListener('scroll', handler, { passive: true });
```

## CLS - Cumulative Layout Shift

**What**: Visual stability during page load  
**Target**: < 0.1  
**Poor**: > 0.25

### Common Causes of Poor CLS
- Images without dimensions
- Dynamically injected content
- Web fonts causing FOIT/FOUT
- Ads/embeds without reserved space

### Optimizations

```html
<!-- Always set dimensions -->
<img src="photo.jpg" width="800" height="600">

<!-- Reserve space for dynamic content -->
<div style="min-height: 250px">
  <!-- Ad will load here -->
</div>

<!-- Preload fonts -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
```

```css
/* Prevent font layout shift */
@font-face {
  font-family: 'MyFont';
  src: url('font.woff2') format('woff2');
  font-display: swap;
}
```

## TBT - Total Blocking Time

**What**: Lab metric for main thread blocking  
**Target**: < 200ms  
**Poor**: > 600ms

### Optimizations
- Code split large bundles
- Defer non-critical scripts
- Use web workers for heavy computation
