react-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Vercel React Best Practices

Vercel React最佳实践

Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
Vercel维护的React和Next.js应用综合性能优化指南,包含8个类别共45条规则,按影响优先级排序,用于指导自动化重构和代码生成。

When to Apply

适用场景

Reference these guidelines when:
  • Writing new React components or Next.js pages
  • Implementing data fetching (client or server-side)
  • Reviewing code for performance issues
  • Refactoring existing React/Next.js code
  • Optimizing bundle size or load times
在以下场景中可参考本指南:
  • 编写新的React组件或Next.js页面
  • 实现客户端或服务端数据获取逻辑
  • 评审代码排查性能问题
  • 重构现有React/Next.js代码
  • 优化包体积或加载速度

Rule Categories by Priority

按优先级排序的规则类别

PriorityCategoryImpactPrefix
1Eliminating WaterfallsCRITICAL
async-
2Bundle Size OptimizationCRITICAL
bundle-
3Server-Side PerformanceHIGH
server-
4Client-Side Data FetchingMEDIUM-HIGH
client-
5Re-render OptimizationMEDIUM
rerender-
6Rendering PerformanceMEDIUM
rendering-
7JavaScript PerformanceLOW-MEDIUM
js-
8Advanced PatternsLOW
advanced-
优先级类别影响程度前缀
1消除请求瀑布严重
async-
2包体积优化严重
bundle-
3服务端性能
server-
4客户端数据获取中高
client-
5重渲染优化
rerender-
6渲染性能
rendering-
7JavaScript性能中低
js-
8高级模式
advanced-

Quick Reference

快速参考

1. Eliminating Waterfalls (CRITICAL)

1. 消除请求瀑布(严重)

  • async-defer-await
    - Move await into branches where actually used
  • async-parallel
    - Use Promise.all() for independent operations
  • async-dependencies
    - Use better-all for partial dependencies
  • async-api-routes
    - Start promises early, await late in API routes
  • async-suspense-boundaries
    - Use Suspense to stream content
  • async-defer-await
    - 将await移到实际使用的分支中
  • async-parallel
    - 独立操作使用Promise.all()并行执行
  • async-dependencies
    - 部分依赖场景使用better-all
  • async-api-routes
    - 在API路由中尽早启动promise,延迟await
  • async-suspense-boundaries
    - 使用Suspense流式传输内容

2. Bundle Size Optimization (CRITICAL)

2. 包体积优化(严重)

  • bundle-barrel-imports
    - Import directly, avoid barrel files
  • bundle-dynamic-imports
    - Use next/dynamic for heavy components
  • bundle-defer-third-party
    - Load analytics/logging after hydration
  • bundle-conditional
    - Load modules only when feature is activated
  • bundle-preload
    - Preload on hover/focus for perceived speed
  • bundle-barrel-imports
    - 直接导入,避免使用barrel文件
  • bundle-dynamic-imports
    - 重型组件使用next/dynamic导入
  • bundle-defer-third-party
    - 水合完成后再加载分析/日志工具
  • bundle-conditional
    - 仅在功能启用时加载对应模块
  • bundle-preload
    - hover/聚焦时预加载资源提升感知速度

3. Server-Side Performance (HIGH)

3. 服务端性能(高)

  • server-cache-react
    - Use React.cache() for per-request deduplication
  • server-cache-lru
    - Use LRU cache for cross-request caching
  • server-serialization
    - Minimize data passed to client components
  • server-parallel-fetching
    - Restructure components to parallelize fetches
  • server-after-nonblocking
    - Use after() for non-blocking operations
  • server-cache-react
    - 使用React.cache()做单次请求内的去重
  • server-cache-lru
    - 使用LRU缓存做跨请求缓存
  • server-serialization
    - 最小化传递给客户端组件的数据量
  • server-parallel-fetching
    - 重构组件结构并行化请求
  • server-after-nonblocking
    - 使用after()处理非阻塞操作

4. Client-Side Data Fetching (MEDIUM-HIGH)

4. 客户端数据获取(中高)

  • client-swr-dedup
    - Use SWR for automatic request deduplication
  • client-event-listeners
    - Deduplicate global event listeners
  • client-swr-dedup
    - 使用SWR自动做请求去重
  • client-event-listeners
    - 全局事件监听器去重

5. Re-render Optimization (MEDIUM)

5. 重渲染优化(中)

  • rerender-defer-reads
    - Don't subscribe to state only used in callbacks
  • rerender-memo
    - Extract expensive work into memoized components
  • rerender-dependencies
    - Use primitive dependencies in effects
  • rerender-derived-state
    - Subscribe to derived booleans, not raw values
  • rerender-functional-setstate
    - Use functional setState for stable callbacks
  • rerender-lazy-state-init
    - Pass function to useState for expensive values
  • rerender-transitions
    - Use startTransition for non-urgent updates
  • rerender-defer-reads
    - 不要订阅仅在回调中使用的状态
  • rerender-memo
    - 将昂贵计算逻辑提取到记忆化组件中
  • rerender-dependencies
    - effect中使用基础类型依赖
  • rerender-derived-state
    - 订阅派生的布尔值而非原始值
  • rerender-functional-setstate
    - 稳定回调使用函数式setState
  • rerender-lazy-state-init
    - 昂贵初始值给useState传函数
  • rerender-transitions
    - 非紧急更新使用startTransition

6. Rendering Performance (MEDIUM)

6. 渲染性能(中)

  • rendering-animate-svg-wrapper
    - Animate div wrapper, not SVG element
  • rendering-content-visibility
    - Use content-visibility for long lists
  • rendering-hoist-jsx
    - Extract static JSX outside components
  • rendering-svg-precision
    - Reduce SVG coordinate precision
  • rendering-hydration-no-flicker
    - Use inline script for client-only data
  • rendering-activity
    - Use Activity component for show/hide
  • rendering-conditional-render
    - Use ternary, not && for conditionals
  • rendering-animate-svg-wrapper
    - 给div包裹层加动画而非SVG元素
  • rendering-content-visibility
    - 长列表使用content-visibility
  • rendering-hoist-jsx
    - 将静态JSX提取到组件外部
  • rendering-svg-precision
    - 降低SVG坐标精度
  • rendering-hydration-no-flicker
    - 仅客户端数据使用内联脚本避免闪烁
  • rendering-activity
    - 显示/隐藏逻辑使用Activity组件
  • rendering-conditional-render
    - 条件渲染使用三元运算符而非&&

7. JavaScript Performance (LOW-MEDIUM)

7. JavaScript性能(中低)

  • js-batch-dom-css
    - Group CSS changes via classes or cssText
  • js-index-maps
    - Build Map for repeated lookups
  • js-cache-property-access
    - Cache object properties in loops
  • js-cache-function-results
    - Cache function results in module-level Map
  • js-cache-storage
    - Cache localStorage/sessionStorage reads
  • js-combine-iterations
    - Combine multiple filter/map into one loop
  • js-length-check-first
    - Check array length before expensive comparison
  • js-early-exit
    - Return early from functions
  • js-hoist-regexp
    - Hoist RegExp creation outside loops
  • js-min-max-loop
    - Use loop for min/max instead of sort
  • js-set-map-lookups
    - Use Set/Map for O(1) lookups
  • js-tosorted-immutable
    - Use toSorted() for immutability
  • js-batch-dom-css
    - 通过类名或cssText批量修改CSS
  • js-index-maps
    - 重复查询提前构建Map
  • js-cache-property-access
    - 循环中缓存对象属性
  • js-cache-function-results
    - 模块级Map缓存函数返回值
  • js-cache-storage
    - 缓存localStorage/sessionStorage读取结果
  • js-combine-iterations
    - 多次filter/map合并为单次循环
  • js-length-check-first
    - 昂贵比较前先检查数组长度
  • js-early-exit
    - 函数提前返回
  • js-hoist-regexp
    - RegExp创建提到循环外部
  • js-min-max-loop
    - 求最值使用循环而非sort
  • js-set-map-lookups
    - O(1)查询使用Set/Map
  • js-tosorted-immutable
    - 不可变排序使用toSorted()

8. Advanced Patterns (LOW)

8. 高级模式(低)

  • advanced-event-handler-refs
    - Store event handlers in refs
  • advanced-use-latest
    - useLatest for stable callback refs
  • advanced-event-handler-refs
    - 事件处理器存储在ref中
  • advanced-use-latest
    - useLatest获取稳定的回调ref

How to Use

使用方法

For detailed explanations and code examples, read the full compiled document:
AGENTS.md
Each rule contains:
  • Brief explanation of why it matters
  • Incorrect code example with explanation
  • Correct code example with explanation
  • Additional context and references
如需详细说明和代码示例,请阅读完整汇编文档:
AGENTS.md
每条规则包含:
  • 规则重要性的简要说明
  • 错误代码示例及说明
  • 正确代码示例及说明
  • 额外上下文和参考资料

Key Examples

核心示例

Promise.all for Independent Operations (CRITICAL)

独立操作使用Promise.all(严重)

typescript
// ❌ Sequential: 3 round trips
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()

// ✅ Parallel: 1 round trip
const [user, posts, comments] = await Promise.all([
  fetchUser(),
  fetchPosts(),
  fetchComments()
])
typescript
// ❌ 顺序执行:3次往返请求
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()

// ✅ 并行执行:1次往返请求
const [user, posts, comments] = await Promise.all([
  fetchUser(),
  fetchPosts(),
  fetchComments()
])

Avoid Barrel File Imports (CRITICAL)

避免Barrel文件导入(严重)

tsx
// ❌ Imports entire library (200-800ms import cost)
import { Check, X, Menu } from 'lucide-react'

// ✅ Imports only what you need
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
tsx
// ❌ 导入整个库(导入耗时200-800ms)
import { Check, X, Menu } from 'lucide-react'

// ✅ 仅导入需要的内容
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'

Dynamic Imports for Heavy Components (CRITICAL)

重型组件使用动态导入(严重)

tsx
// ❌ Monaco bundles with main chunk ~300KB
import { MonacoEditor } from './monaco-editor'

// ✅ Monaco loads on demand
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
  () => import('./monaco-editor').then(m => m.MonacoEditor),
  { ssr: false }
)
tsx
// ❌ Monaco打包进主chunk,体积约300KB
import { MonacoEditor } from './monaco-editor'

// ✅ Monaco按需加载
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
  () => import('./monaco-editor').then(m => m.MonacoEditor),
  { ssr: false }
)

Use Functional setState (MEDIUM)

使用函数式setState(中)

tsx
// ❌ Requires state as dependency, stale closure risk
const addItems = useCallback((newItems) => {
  setItems([...items, ...newItems])
}, [items])

// ✅ Stable callback, no stale closures
const addItems = useCallback((newItems) => {
  setItems(curr => [...curr, ...newItems])
}, [])
tsx
// ❌ 需要将state作为依赖,存在闭包陈旧风险
const addItems = useCallback((newItems) => {
  setItems([...items, ...newItems])
}, [items])

// ✅ 稳定回调,无闭包陈旧问题
const addItems = useCallback((newItems) => {
  setItems(curr => [...curr, ...newItems])
}, [])

Constraints

约束规则

필수 규칙 (MUST)

必须遵守的规则(MUST)

  1. Waterfall 제거: Promise.all, Suspense 사용
  2. 번들 최적화: barrel imports 금지, dynamic imports 사용
  3. RSC 경계: 필요한 데이터만 직렬화
  1. 消除请求瀑布:使用Promise.all、Suspense
  2. 包体积优化:禁止使用barrel imports,使用dynamic imports
  3. RSC边界:仅序列化必要数据

금지 사항 (MUST NOT)

禁止事项(MUST NOT)

  1. Sequential await: 독립적인 fetch를 순차 실행하지 않음
  2. Array mutations: sort() 대신 toSorted() 사용
  3. Inline objects in React.cache: 캐시 미스 발생
  1. 顺序await:不得顺序执行独立的fetch请求
  2. 数组突变:使用toSorted()代替sort()
  3. React.cache中传入内联对象:会导致缓存失效

References

参考资料

Metadata

元数据

버전

版本

  • 현재 버전: 1.0.0
  • 최종 업데이트: 2026-01-22
  • 호환 플랫폼: Claude, ChatGPT, Gemini
  • 원본 출처: vercel/agent-skills
  • 当前版本: 1.0.0
  • 最后更新: 2026-01-22
  • 兼容平台: Claude, ChatGPT, Gemini
  • 原始来源: vercel/agent-skills

관련 스킬

相关技能

  • performance-optimization: 일반 성능 최적화
  • state-management: 상태 관리
  • performance-optimization: 通用性能优化
  • state-management: 状态管理

태그

标签

#React
#Next.js
#performance
#optimization
#vercel
#waterfalls
#bundle-size
#RSC
#frontend
#React
#Next.js
#performance
#optimization
#vercel
#waterfalls
#bundle-size
#RSC
#frontend