Web Performance & Core Web Vitals
Overview
Enforces high-efficiency frontend and full-stack performance standards to achieve exceptional Core Web Vitals: Largest Contentful Paint (LCP < 2.5s), Interaction to Next Paint (INP < 200ms), and Cumulative Layout Shift (CLS < 0.1).
When to Use
Activate whenever analyzing, profiling, writing, or optimizing page loading speeds, network waterfalls, script bundling, animation frame rates, or data caching.
Negative Constraints (What NOT to Do)
- NEVER introduce async waterfalls: Do not chain sequential
await calls when requests can be executed concurrently via Promise.all().
- NEVER import large full libraries when only a utility is needed: Never
import _ from 'lodash'; use import debounce from 'lodash/debounce' or native alternatives.
- NEVER render images or videos without explicit aspect ratios: Always provide
width and height or aspect-ratio to avoid Cumulative Layout Shift (CLS).
- NEVER trigger synchronous layout thrashing: Do not alternate between reading layout properties (
offsetHeight, getBoundingClientRect) and writing styles in loops.
- NEVER animate non-composited properties: Animate only GPU-composited CSS properties (
transform, opacity). Never animate width, height, top, left, or margin.
Rules & Patterns
1. Vercel Optimization Hierarchy by Impact
| Priority |
Category |
Key Optimization Target |
Expected Impact |
| 1. CRITICAL |
Eliminating Waterfalls |
Parallel data fetching (Promise.all), Suspense streaming |
30–60% faster LCP |
| 2. CRITICAL |
Bundle Size Optimization |
Direct submodule imports, next/dynamic, deferring 3rd party scripts |
40–70% smaller initial JS |
| 3. HIGH |
Server-Side & RSC Caching |
React.cache() request deduplication, edge SSR caching |
Lower TTFB & DB load |
| 4. MEDIUM-HIGH |
Client Query Optimization |
SWR / TanStack Query stale-while-revalidate, deduplication |
Zero redundant network calls |
| 5. MEDIUM |
Render & DOM Optimization |
Virtualization for large lists, state colocation, :focus-visible |
Smooth 60 FPS / INP < 100ms |
2. Eliminating Network Waterfalls
// [GOOD] Parallel execution
const [user, notifications] = await Promise.all([
fetchUser(),
fetchNotifications(),
]);
const posts = await fetchPosts(user.id);
3. Layout Shift & Visual Stability (CLS < 0.1)
- Images & Video: Always supply
width, height, and sizes or CSS aspect-ratio: 16 / 9.
- Dynamic Content: Reserve layout space for dynamically loaded widgets with min-height placeholders or skeletons.
- Tabular Numbers: Use
font-feature-settings: "tnum" / font-variant-numeric: tabular-nums for counters, clocks, and tables to prevent number width jitter.
Code Examples
See EXAMPLES.md for detailed performance patterns and benchmark snippets.
Validation Checklist
Common Mistakes
- Chaining independent async requests instead of using
Promise.all.
- Animating layout-triggering properties (
height, width, top) causing jank.
- Missing image dimensions causing layout shift when images finish loading.
Integration Notes
- Pairs with
nextjs and react for App Router caching and component lifecycle tuning.
- Pairs with
ui-ux-pro for smooth animations and responsive design tokens.
performance Examples — Anti-patterns vs ContextOS Standard
Example 1: Dynamic Imports for Heavy Libraries
Anti-pattern: Static Import of Heavy Visualizers in Initial Bundle
// BAD: Adds 800KB (Monaco editor or Three.js) to the critical first-paint bundle!
import { CodeEditor } from '@/components/CodeEditor';
export default function Page() {
return <div><CodeEditor /></div>;
}
Best practice: ContextOS Standard (Lazy Load on Demand)
// GOOD: Dynamic import splits chunk, only downloads when component renders
import dynamic from 'next/dynamic';
const CodeEditor = dynamic(
() => import('@/components/CodeEditor'),
{ loading: () => <EditorSkeleton />, ssr: false }
);
export default function Page() {
return <div><CodeEditor /></div>;
}
performance Troubleshooting & Common Mistakes
1. Cumulative Layout Shift (CLS) from Images & Fonts
- Symptom: Page content jumps around as images and custom fonts load.
- Root Cause: Missing width and height attributes on image tags and FOUT (Flash of Unstyled Text).
- Fix: Always specify aspect-ratio or width/height on images, and use next/font to preload web fonts with fallback sizing.
2. High Interaction to Next Paint (INP)
- Symptom: User clicks a button and the UI freezes for 200ms+ before responding.
- Root Cause: Long task blocking the main thread during event dispatch.
- Fix: Defer non-critical state updates using startTransition() or split heavy computation with Web Workers.
3. Unoptimized SVG / Icon Overload
- Symptom: Huge DOM node count and slow initial render times.
- Root Cause: Rendering 500 inline SVG icons with complex paths.
- Fix: Use SVG sprite sheets, dynamic icon loaders, or lightweight canvas rendering for dense data visualizations.
1---2name: performance3description: Web Performance & Core Web Vitals4---5# Web Performance & Core Web Vitals67## Overview89Enforces high-efficiency frontend and full-stack performance standards to achieve exceptional Core Web Vitals: Largest Contentful Paint (LCP < 2.5s), Interaction to Next Paint (INP < 200ms), and Cumulative Layout Shift (CLS < 0.1).1011## When to Use1213Activate whenever analyzing, profiling, writing, or optimizing page loading speeds, network waterfalls, script bundling, animation frame rates, or data caching.1415## Negative Constraints (What NOT to Do)16171. **NEVER introduce async waterfalls**: Do not chain sequential `await` calls when requests can be executed concurrently via `Promise.all()`.182. **NEVER import large full libraries when only a utility is needed**: Never `import _ from 'lodash'`; use `import debounce from 'lodash/debounce'` or native alternatives.193. **NEVER render images or videos without explicit aspect ratios**: Always provide `width` and `height` or `aspect-ratio` to avoid Cumulative Layout Shift (CLS).204. **NEVER trigger synchronous layout thrashing**: Do not alternate between reading layout properties (`offsetHeight`, `getBoundingClientRect`) and writing styles in loops.215. **NEVER animate non-composited properties**: Animate only GPU-composited CSS properties (`transform`, `opacity`). Never animate `width`, `height`, `top`, `left`, or `margin`.2223## Rules & Patterns2425### 1. Vercel Optimization Hierarchy by Impact2627| Priority | Category | Key Optimization Target | Expected Impact |28|:---|:---|:---|:---|29| **1. CRITICAL** | **Eliminating Waterfalls** | Parallel data fetching (`Promise.all`), Suspense streaming | **30–60% faster LCP** |30| **2. CRITICAL** | **Bundle Size Optimization** | Direct submodule imports, `next/dynamic`, deferring 3rd party scripts | **40–70% smaller initial JS** |31| **3. HIGH** | **Server-Side & RSC Caching** | `React.cache()` request deduplication, edge SSR caching | **Lower TTFB & DB load** |32| **4. MEDIUM-HIGH** | **Client Query Optimization** | SWR / TanStack Query stale-while-revalidate, deduplication | **Zero redundant network calls** |33| **5. MEDIUM** | **Render & DOM Optimization** | Virtualization for large lists, state colocation, `:focus-visible` | **Smooth 60 FPS / INP < 100ms** |3435### 2. Eliminating Network Waterfalls3637```ts38// [GOOD] Parallel execution39const [user, notifications] = await Promise.all([40 fetchUser(),41 fetchNotifications(),42]);43const posts = await fetchPosts(user.id);44```4546### 3. Layout Shift & Visual Stability (CLS < 0.1)4748- **Images & Video**: Always supply `width`, `height`, and `sizes` or CSS `aspect-ratio: 16 / 9`.49- **Dynamic Content**: Reserve layout space for dynamically loaded widgets with min-height placeholders or skeletons.50- **Tabular Numbers**: Use `font-feature-settings: "tnum"` / `font-variant-numeric: tabular-nums` for counters, clocks, and tables to prevent number width jitter.5152## Code Examples5354See `EXAMPLES.md` for detailed performance patterns and benchmark snippets.5556## Validation Checklist5758- [ ] LCP target is < 2.5s with preloaded critical fonts and LCP image `priority`.59- [ ] No sequential `await` waterfalls in API routes or Server Components.60- [ ] All animated elements use only `transform` and `opacity`.61- [ ] `prefers-reduced-motion` media queries are respected.62- [ ] Large tables / lists (> 100 items) utilize virtualization.6364## Common Mistakes6566- Chaining independent async requests instead of using `Promise.all`.67- Animating layout-triggering properties (`height`, `width`, `top`) causing jank.68- Missing image dimensions causing layout shift when images finish loading.6970## Integration Notes7172- Pairs with `nextjs` and `react` for App Router caching and component lifecycle tuning.73- Pairs with `ui-ux-pro` for smooth animations and responsive design tokens.747576# performance Examples — Anti-patterns vs ContextOS Standard7778## Example 1: Dynamic Imports for Heavy Libraries7980### Anti-pattern: Static Import of Heavy Visualizers in Initial Bundle8182```typescript83// BAD: Adds 800KB (Monaco editor or Three.js) to the critical first-paint bundle!84import { CodeEditor } from '@/components/CodeEditor';8586export default function Page() {87 return <div><CodeEditor /></div>;88}89```9091### Best practice: ContextOS Standard (Lazy Load on Demand)9293```typescript94// GOOD: Dynamic import splits chunk, only downloads when component renders95import dynamic from 'next/dynamic';9697const CodeEditor = dynamic(98 () => import('@/components/CodeEditor'),99 { loading: () => <EditorSkeleton />, ssr: false }100);101102export default function Page() {103 return <div><CodeEditor /></div>;104}105```106107# performance Troubleshooting & Common Mistakes108109## 1. Cumulative Layout Shift (CLS) from Images & Fonts110111- **Symptom**: Page content jumps around as images and custom fonts load.112- **Root Cause**: Missing width and height attributes on image tags and FOUT (Flash of Unstyled Text).113- **Fix**: Always specify aspect-ratio or width/height on images, and use next/font to preload web fonts with fallback sizing.114115## 2. High Interaction to Next Paint (INP)116117- **Symptom**: User clicks a button and the UI freezes for 200ms+ before responding.118- **Root Cause**: Long task blocking the main thread during event dispatch.119- **Fix**: Defer non-critical state updates using startTransition() or split heavy computation with Web Workers.120121## 3. Unoptimized SVG / Icon Overload122123- **Symptom**: Huge DOM node count and slow initial render times.124- **Root Cause**: Rendering 500 inline SVG icons with complex paths.125- **Fix**: Use SVG sprite sheets, dynamic icon loaders, or lightweight canvas rendering for dense data visualizations.