| name | react-best-practices |
|---|---|
| description | Comprehensive React and Next.js performance optimization guide with 40+ rules for eliminating waterfalls, optimizing bundles, and improving rendering. Use when optimizing React apps, reviewing performance, or refactoring components. |
| version | 1.0.0 |
| author | Vercel Engineering |
| license | MIT |
| tags | ["React", "Next.js", "Performance", "Optimization", "Best Practices", "Bundle Size", "Rendering", "Server Components"] |
| dependencies | [] |
React Best Practices - Performance Optimization
Comprehensive performance optimization guide for React and Next.js applications with 40+ rules organized by impact level. Designed to help developers eliminate performance bottlenecks and follow best practices.
When to use this skill
Use React Best Practices when: - Optimizing React or Next.js application performance - Reviewing code for performance improvements - Refactoring existing components for better performance - Implementing new features with performance in mind - Debugging slow rendering or loading issues - Reducing bundle size - Eliminating request waterfalls
Key areas covered: - Eliminating Waterfalls (CRITICAL): Prevent sequential async operations - Bundle Size Optimization (CRITICAL): Reduce initial JavaScript payload - Server-Side Performance (HIGH): Optimize RSC and data fetching - Client-Side Data Fetching (MEDIUM-HIGH): Implement efficient caching - Re-render Optimization (MEDIUM): Minimize unnecessary re-renders - Rendering Performance (MEDIUM): Optimize browser rendering - JavaScript Performance (LOW-MEDIUM): Micro-optimizations for hot paths - Advanced Patterns (LOW): Specialized techniques for edge cases
Quick reference
Critical priorities
- Defer await until needed - Move awaits into branches where they're used
- Use Promise.all() - Parallelize independent async operations
- Avoid barrel imports - Import directly from source files
- Dynamic imports - Lazy-load heavy components
- Strategic Suspense - Stream content while showing layout
Common patterns
Parallel data fetching:
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
])
Direct imports:
// ❌ Loads entire library
import { Check } from 'lucide-react'
// ✅ Loads only what you need
import Check from 'lucide-react/dist/esm/icons/check'
Dynamic components:
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
() => import('./monaco-editor'),
{ ssr: false }
)
Using the guidelines
The complete performance guidelines are available in the references folder:
- react-performance-guidelines.md: Complete guide with all 40+ rules, code examples, and impact analysis
Each rule includes: - Incorrect/correct code comparisons - Specific impact metrics - When to apply the optimization - Real-world examples
Categories overview
1. Eliminating Waterfalls (CRITICAL)
Waterfalls are the #1 performance killer. Each sequential await adds full network latency. - Defer await until needed - Dependency-based parallelization - Prevent waterfall chains in API routes - Promise.all() for independent operations - Strategic Suspense boundaries
2. Bundle Size Optimization (CRITICAL)
Reducing initial bundle size improves Time to Interactive and Largest Contentful Paint. - Avoid barrel file imports - Conditional module loading - Defer non-critical third-party libraries - Dynamic imports for heavy components - Preload based on user intent
3. Server-Side Performance (HIGH)
Optimize server-side rendering and data fetching. - Cross-request LRU caching - Minimize serialization at RSC boundaries - Parallel data fetching with component composition - Per-request deduplication with React.cache()
4. Client-Side Data Fetching (MEDIUM-HIGH)
Automatic deduplication and efficient data fetching patterns. - Deduplicate global event listeners - Use SWR for automatic deduplication
5. Re-render Optimization (MEDIUM)
Reduce unnecessary re-renders to minimize wasted computation. - Defer state reads to usage point - Extract to memoized components - Narrow effect dependencies - Subscribe to derived state - Use lazy state initialization - Use transitions for non-urgent updates
6. Rendering Performance (MEDIUM)
Optimize the browser rendering process. - Animate SVG wrapper instead of SVG element - CSS content-visibility for long lists - Hoist static JSX elements - Optimize SVG precision - Prevent hydration mismatch without flickering - Use Activity component for show/hide - Use explicit conditional rendering
7. JavaScript Performance (LOW-MEDIUM)
Micro-optimizations for hot paths. - Batch DOM CSS changes - Build index maps for repeated lookups - Cache property access in loops - Cache repeated function calls - Cache storage API calls - Combine multiple array iterations - Early length check for array comparisons - Early return from functions - Hoist RegExp creation - Use loop for min/max instead of sort - Use Set/Map for O(1) lookups - Use toSorted() instead of sort()
8. Advanced Patterns (LOW)
Specialized techniques for edge cases. - Store event handlers in refs - useLatest for stable callback refs
Implementation approach
When optimizing a React application:
- Profile first: Use React DevTools Profiler and browser performance tools to identify bottlenecks
- Focus on critical paths: Start with eliminating waterfalls and reducing bundle size
- Measure impact: Verify improvements with metrics (LCP, TTI, FID)
- Apply incrementally: Don't over-optimize prematurely
- Test thoroughly: Ensure optimizations don't break functionality
Key metrics to track
- Time to Interactive (TTI): When page becomes fully interactive
- Largest Contentful Paint (LCP): When main content is visible
- First Input Delay (FID): Responsiveness to user interactions
- Cumulative Layout Shift (CLS): Visual stability
- Bundle size: Initial JavaScript payload
- Server response time: TTFB for server-rendered content
Common pitfalls to avoid
❌ Don't: - Use barrel imports from large libraries - Block parallel operations with sequential awaits - Re-render entire trees when only part needs updating - Load analytics/tracking in the critical path - Mutate arrays with .sort() instead of .toSorted() - Create RegExp or heavy objects inside render
✅ Do: - Import directly from source files - Use Promise.all() for independent operations - Memoize expensive components - Lazy-load non-critical code - Use immutable array methods - Hoist static objects outside components
Resources
- React Documentation
- Next.js Documentation
- SWR Documentation
- Vercel Bundle Optimization
- Vercel Dashboard Performance
- better-all Library
- node-lru-cache
Version history
v0.1.0 (January 2026) - Initial release from Vercel Engineering - 40+ performance rules across 8 categories - Comprehensive code examples and impact analysis