render-optimization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Render Optimization
React 渲染性能优化
Modern render performance patterns for React 19+.
适用于React 19+的现代渲染性能优化模式。
Decision Tree: React Compiler First (2026)
决策树:优先使用React Compiler(2026年)
Is React Compiler enabled?
├─ YES → Let compiler handle memoization automatically
│ Only use useMemo/useCallback as escape hatches
│ DevTools shows "Memo ✨" badge
│
└─ NO → Profile first, then optimize
1. React DevTools Profiler
2. Identify actual bottlenecks
3. Apply targeted optimizations是否启用了React Compiler?
├─ 是 → 让编译器自动处理记忆化
│ 仅在特殊场景下使用useMemo/useCallback作为兜底方案
│ DevTools会显示“Memo ✨”标识
│
└─ 否 → 先进行性能分析,再做优化
1. 使用React DevTools Profiler
2. 定位实际性能瓶颈
3. 应用针对性的优化措施React Compiler (Primary Approach)
React Compiler(首选方案)
React 19's compiler automatically memoizes:
- Component re-renders
- Intermediate values (like useMemo)
- Callback references (like useCallback)
- JSX elements
tsx
// next.config.js (Next.js 16+)
const nextConfig = {
reactCompiler: true,
}
// Expo SDK 54+ enables by defaultVerification: Open React DevTools → Look for "Memo ✨" badge
React 19的编译器会自动对以下内容进行记忆化:
- 组件重渲染
- 中间值(类似useMemo的作用)
- 回调引用(类似useCallback的作用)
- JSX元素
tsx
// next.config.js (Next.js 16+)
const nextConfig = {
reactCompiler: true,
}
// Expo SDK 54+ 默认启用验证方式:打开React DevTools → 查找“Memo ✨”标识
When Manual Memoization Still Needed
仍需手动记忆化的场景
Use / as escape hatches when:
useMemouseCallbacktsx
// 1. Effect dependencies that shouldn't trigger re-runs
const stableConfig = useMemo(() => ({
apiUrl: process.env.API_URL
}), [])
useEffect(() => {
initializeSDK(stableConfig)
}, [stableConfig])
// 2. Third-party libraries without compiler support
const memoizedValue = useMemo(() =>
expensiveThirdPartyComputation(data), [data])
// 3. Precise control over memoization boundaries
const handleClick = useCallback(() => {
// Critical callback that must be stable
}, [dependency])在以下场景中,将/作为兜底方案使用:
useMemouseCallbacktsx
// 1. 不应触发重渲染的Effect依赖项
const stableConfig = useMemo(() => ({
apiUrl: process.env.API_URL
}), [])
useEffect(() => {
initializeSDK(stableConfig)
}, [stableConfig])
// 2. 不支持编译器的第三方库
const memoizedValue = useMemo(() =>
expensiveThirdPartyComputation(data), [data])
// 3. 精确控制记忆化边界
const handleClick = useCallback(() => {
// 必须保持稳定的关键回调
}, [dependency])Virtualization Thresholds
虚拟化阈值
| Item Count | Recommendation |
|---|---|
| < 100 | Regular rendering usually fine |
| 100-500 | Consider virtualization |
| 500+ | Virtualization required |
tsx
import { useVirtualizer } from '@tanstack/react-virtual'
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
overscan: 5,
})| 条目数量 | 推荐方案 |
|---|---|
| < 100 | 常规渲染通常即可满足需求 |
| 100-500 | 考虑使用虚拟化 |
| 500+ | 必须使用虚拟化 |
tsx
import { useVirtualizer } from '@tanstack/react-virtual'
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
overscan: 5,
})State Colocation
状态就近原则
Move state as close to where it's used as possible:
tsx
// ❌ State too high - causes unnecessary re-renders
function App() {
const [filter, setFilter] = useState('')
return (
<Header /> {/* Re-renders on filter change! */}
<FilterInput value={filter} onChange={setFilter} />
<List filter={filter} />
)
}
// ✅ State colocated - minimal re-renders
function App() {
return (
<Header />
<FilterableList /> {/* State inside */}
)
}将状态尽可能移至其使用位置附近:
tsx
// ❌ 状态层级过高 - 导致不必要的重渲染
function App() {
const [filter, setFilter] = useState('')
return (
<Header /> {/* 会随filter变化而重渲染! */}
<FilterInput value={filter} onChange={setFilter} />
<List filter={filter} />
)
}
// ✅ 状态就近放置 - 最小化重渲染
function App() {
return (
<Header />
<FilterableList /> {/* 状态内部维护 */}
)
}Profiling Workflow
性能分析流程
- React DevTools Profiler: Record, interact, analyze
- Identify: Components with high render counts or duration
- Verify: Is the re-render actually causing perf issues?
- Fix: Apply targeted optimization
- Measure: Confirm improvement
- React DevTools Profiler:录制、交互、分析
- 定位问题:找出渲染次数过多或耗时过长的组件
- 验证影响:确认该重渲染是否真的造成了性能问题
- 修复优化:应用针对性的优化措施
- 效果验证:确认优化后的性能提升
Quick Wins
快速优化技巧
- Key prop: Stable, unique keys for lists
- Lazy loading: for code splitting
React.lazy() - Debounce: Input handlers with
useDeferredValue - Suspense: Streaming with proper boundaries
- Key属性:为列表项提供稳定且唯一的key
- 懒加载:使用进行代码分割
React.lazy() - 防抖处理:使用处理输入回调
useDeferredValue - Suspense:合理设置边界实现流式渲染
Key Decisions
关键决策
| Decision | Recommendation |
|---|---|
| Memoization | Let React Compiler handle it (2026 default) |
| Lists 100+ items | Use TanStack Virtual |
| State placement | Colocate as close to usage as possible |
| Profiling | Always measure before optimizing |
| 决策场景 | 推荐方案 |
|---|---|
| 记忆化处理 | 优先让React Compiler自动处理(2026年默认启用) |
| 100+条目的列表 | 使用TanStack Virtual |
| 状态放置 | 尽可能就近放置到使用位置 |
| 性能优化 | 优化前务必先进行性能测量 |
Related Skills
相关技能
- - Server-first rendering
react-server-components-framework - - Build optimization
vite-advanced - - Performance testing with Playwright
e2e-testing
- - 服务端优先渲染
react-server-components-framework - - 构建优化
vite-advanced - - 使用Playwright进行性能测试
e2e-testing
References
参考资料
- React Compiler Migration - Compiler adoption
- Memoization Escape Hatches - When useMemo needed
- TanStack Virtual - Virtualization
- State Colocation - State placement
- DevTools Profiler - Finding bottlenecks
- React Compiler Migration - 编译器迁移指南
- Memoization Escape Hatches - 何时需要使用useMemo
- TanStack Virtual - 虚拟化方案
- State Colocation - 状态放置原则
- DevTools Profiler - 性能瓶颈定位