web-performance-web-performance · git:20260202.b236384 · 2026-02-02 · sha256 7afdece01b08806a

web-performance-web-performance git:20260202.b236384A

Immutable. This exact content is served forever at /api/v1/blob/7afdece01b08806a.

---
name: web-performance-web-performance
description: Bundle optimization, render performance
---

# Performance Standards

> **Quick Guide:** Build performance? Turborepo caching with >80% hit rate. Bundle budgets? < 200KB main bundle. Core Web Vitals? LCP < 2.5s, INP < 200ms, CLS < 0.1. React patterns? Strategic memo/useMemo (or React Compiler), lazy loading, virtualization for 100+ items. Monitoring? Real User Monitoring with web-vitals library.

---

<critical_requirements>

## CRITICAL: Before Optimizing Performance

**(You MUST set performance budgets BEFORE building features - bundle size limits, Core Web Vitals targets, build time thresholds)**

**(You MUST profile BEFORE optimizing - measure actual bottlenecks with Chrome DevTools, React Profiler, or Lighthouse)**

**(You MUST use named constants for ALL performance thresholds - no magic numbers like `< 200KB` or `< 2.5s`)**

**(You MUST monitor Core Web Vitals in production with web-vitals library - track LCP, INP, CLS for real users)**

**(You MUST lazy load route components and heavy libraries - code splitting prevents large initial bundles)**

</critical_requirements>

---

**Detailed Resources:**

- For code examples, see [examples.md](examples.md)
- For decision frameworks and anti-patterns, see [reference.md](reference.md)

---

**Auto-detection:** Core Web Vitals, bundle size optimization, LCP, INP, CLS, FID, lazy loading, memoization, React Compiler, performance monitoring, web-vitals library, Turborepo caching, bundle budget, virtualization

**When to use:**

- Optimizing Core Web Vitals (LCP < 2.5s, INP < 200ms, CLS < 0.1)
- Setting and enforcing bundle size budgets (< 200KB main bundle)
- Implementing React performance patterns (strategic memo, lazy loading, virtualization)
- Monitoring performance with web-vitals library in production
- Configuring Turborepo caching for build performance (> 80% cache hit rate)

**When NOT to use:**

- Before measuring (premature optimization adds complexity without benefit)
- For simple components (memoizing cheap renders adds overhead)
- Internal admin tools with < 10 users (ROI too low)
- Prototypes and MVPs (optimize after validating product-market fit)

**Key patterns covered:**

- Core Web Vitals targets (LCP < 2.5s, INP < 200ms, CLS < 0.1)
- Bundle size budgets (< 200KB main, < 500KB total initial load)
- Strategic React optimization (memo/useMemo when needed, not everywhere - profile first)
- Image optimization (WebP/AVIF, lazy loading, Next.js Image component)
- Build performance with Turborepo caching and parallel execution

---

<philosophy>

## Philosophy

Performance is a feature, not an afterthought. Fast applications improve user experience, conversion rates, and SEO rankings. Performance optimization requires measurement before action, budgets before building, and monitoring in production.

**Core performance principles:**

- **Measure first, optimize second** - Profile actual bottlenecks, don't guess
- **Set budgets early** - Define bundle size limits and Core Web Vitals targets before building
- **Monitor real users** - Lab metrics (Lighthouse) differ from real-world performance (RUM)
- **Optimize strategically** - Memoize expensive operations, not everything
- **Lazy load by default** - Load code when needed, not upfront

</philosophy>

---

<patterns>

## Core Patterns

### Pattern 1: Build Performance with Turborepo Caching

Use Turborepo to cache build artifacts across machines (local and CI). Target > 80% cache hit rate for optimal build performance.

#### Build Time Targets

```typescript
// constants/performance.ts
export const BUILD_TIME_TARGETS = {
  FULL_BUILD_COLD_CACHE_MINUTES: 2,
  INCREMENTAL_BUILD_WARM_CACHE_SECONDS: 30,
  DEVELOPMENT_REBUILD_HMR_SECONDS: 5,
  PRODUCTION_BUILD_MINUTES: 5,
} as const;

export const CACHE_HIT_RATE_TARGET_PERCENT = 80;
```

**Targets:**

- **Full build** (cold cache): < 2 min
- **Incremental build** (warm cache): < 30s
- **Development rebuild** (HMR): < 5s
- **Production build**: < 5 min
- **Cache hit rate**: > 80%

For detailed Turborepo configuration examples, see [examples.md](examples.md#turborepo-configuration).

---

### Pattern 2: Bundle Size Budgets

Set and enforce bundle size limits to prevent bloat. Main bundle should be < 200KB gzipped for fast downloads on 3G networks.

#### Bundle Size Constants

```typescript
// constants/bundle-budgets.ts
export const BUNDLE_SIZE_BUDGETS_KB = {
  MAIN_BUNDLE_GZIPPED: 200,
  VENDOR_BUNDLE_GZIPPED: 150,
  ROUTE_BUNDLE_GZIPPED: 100,
  TOTAL_INITIAL_LOAD_GZIPPED: 500,
  MAIN_CSS_GZIPPED: 50,
  CRITICAL_CSS_INLINE: 14, // Fits in first TCP packet
} as const;

export const IMAGE_SIZE_BUDGETS_KB = {
  HERO_IMAGE: 200,
  THUMBNAIL: 50,
} as const;
```

#### Recommended Budgets

**JavaScript bundles:**

- **Main bundle**: < 200 KB (gzipped)
- **Vendor bundle**: < 150 KB (gzipped)
- **Route bundles**: < 100 KB each (gzipped)
- **Total initial load**: < 500 KB (gzipped)

**Why these limits:** 200 KB ≈ 1 second download on 3G, faster Time to Interactive (TTI), better mobile performance

**CSS bundles:**

- **Main CSS**: < 50 KB (gzipped)
- **Critical CSS**: < 14 KB (inlined, fits in first TCP packet)

**Images:**

- **Hero images**: < 200 KB (use WebP/AVIF)
- **Thumbnails**: < 50 KB
- **Icons**: Use SVG or icon fonts

For code splitting and bundle analysis examples, see [examples.md](examples.md#code-splitting-strategies).

---

### Pattern 3: Core Web Vitals Optimization

Optimize for Google's Core Web Vitals: LCP < 2.5s, INP < 200ms, CLS < 0.1. These metrics impact SEO and user experience.

**Note:** INP (Interaction to Next Paint) replaced FID (First Input Delay) as a Core Web Vital on March 12, 2024. FID is now deprecated.

#### Core Web Vitals Constants

```typescript
// constants/web-vitals.ts
export const CORE_WEB_VITALS_THRESHOLDS = {
  LCP_SECONDS: 2.5, // Largest Contentful Paint
  FID_MS: 100, // First Input Delay
  INP_MS: 200, // Interaction to Next Paint (replacing FID)
  CLS_SCORE: 0.1, // Cumulative Layout Shift
  FCP_SECONDS: 1.8, // First Contentful Paint
  TTI_SECONDS: 3.8, // Time to Interactive
  TBT_MS: 300, // Total Blocking Time
  TTFB_MS: 800, // Time to First Byte
} as const;
```

#### LCP (Largest Contentful Paint): < 2.5s

Measures loading performance. When largest element becomes visible.

**How to improve:**

- Optimize images (WebP, lazy loading)
- Minimize render-blocking resources
- Use CDN for static assets
- Server-side rendering (SSR) or Static Site Generation (SSG)

#### INP (Interaction to Next Paint): < 200ms

Measures interactivity. Time from user interaction to next visual update. INP replaced FID as a Core Web Vital on March 12, 2024.

**Why INP replaced FID:** FID only measured the first interaction and only the input delay. INP measures ALL interactions throughout the page visit, including input delay, processing time, and presentation delay.

**How to improve:**

- Minimize JavaScript execution time
- Code splitting (load less JS upfront)
- Use web workers for heavy computation
- Debounce/throttle expensive event handlers
- Break up long tasks (> 50ms) with `scheduler.yield()` or `setTimeout`

#### CLS (Cumulative Layout Shift): < 0.1

Measures visual stability. Prevents unexpected layout shifts.

**How to improve:**

- Set image/video dimensions
- Reserve space for dynamic content
- Avoid injecting content above existing content
- Use `font-display: swap` with size-adjust

For detailed Core Web Vitals examples and production monitoring setup, see [examples.md](examples.md#core-web-vitals-examples).

</patterns>

---

<critical_reminders>

## CRITICAL REMINDERS

**(You MUST set performance budgets BEFORE building features - bundle size limits, Core Web Vitals targets, build time thresholds)**

**(You MUST profile BEFORE optimizing - measure actual bottlenecks with Chrome DevTools, React Profiler, or Lighthouse)**

**(You MUST use named constants for ALL performance thresholds - no magic numbers like `< 200KB` or `< 2.5s`)**

**(You MUST monitor Core Web Vitals in production with web-vitals library - track LCP, INP, CLS for real users)**

**(You MUST lazy load route components and heavy libraries - code splitting prevents large initial bundles)**

**Failure to follow these rules will result in slow applications, poor Core Web Vitals, large bundles, and degraded user experience.**

</critical_reminders>