React Optimise 是一份面向 React 应用的应用级性能优化最佳实践指南,共包含 43 条规则,分为 8 个类别,按影响程度从关键(React Compiler、打包优化)到渐进(内存管理)排序。
适用场景
- 优化 React 应用性能或打包体积
- 采用或排查 React Compiler v1.0 问题
- 拆分打包并配置代码分割
- 改善 Core Web Vitals(INP、LCP、CLS)
- 剖析渲染性能并定位瓶颈
- 修复长期运行的单页应用中的内存泄漏
- 优化数据获取模式并消除请求瀑布
规则类别
- React Compiler 精通(关键,6 条):编译器友好代码、bailout 检测、增量采用。
- 打包与加载(关键,6 条):路由拆分、消除 barrel 文件、动态导入、预取。
- 渲染优化(高,6 条):虚拟化、children 模式、防抖、CSS containment。
- 数据获取性能(高,5 条):消除瀑布、路由预加载、SWR、去重。
- Core Web Vitals(中高,5 条):INP 让出、LCP 优先级、CLS 预防、图片优化。
- 状态与订阅性能(中高,5 条):Context 拆分、选择器、原子状态、派生状态。
- 剖析与度量(中,5 条):DevTools 剖析、火焰图、CI 预算、生产构建。
- 内存管理(低中,5 条):effect 清理、异步取消、闭包泄漏、堆分析。
快速参考
关键模式(优先处理):
- 编写编译器友好组件以解锁自动 2-10 倍优化
- 在路由边界拆分代码,将初始打包体积减少 40-70%
- 消除 barrel 文件以启用 tree shaking
- 检测并修复静默的编译器 bailout
常见错误(避免这些反模式):
- 在渲染期间读取 ref(破坏编译器优化)
- 仅使用一个函数却导入整个库
- 优化前未做剖析(针对错误的瓶颈)
- 缺少 effect 清理(订阅内存泄漏)
目录
-
React Compiler 精通 — 关键 1.1 检测并修复静默的编译器 Bailout — 关键(防止丢失自动记忆化) 1.2 将副作用与渲染隔离以保证编译器正确性 — 关键(防止编译器产生错误的缓存输出) 1.3 采用编译器后移除手动记忆化 — 关键(组件文件代码减少 20-40%) 1.4 使用指令进行增量编译器采用 — 关键(无需全代码库迁移即可安全上线) 1.5 使用支持编译的 Ref 访问模式 — 关键(为使用 ref 的组件保持编译器优化) 1.6 编写编译器友好的组件模式 — 关键(自动 2-10 倍渲染优化)
-
打包与加载 — 关键 2.1 配置依赖以实现有效的 Tree Shaking — 关键(依赖中 50-90% 死代码消除) 2.2 消除 Barrel 文件以启用 Tree Shaking — 关键(消除 200-800ms 导入成本) 2.3 使用分析工具强制执行打包体积预算 — 关键(防止打包体积逐渐回归) 2.4 在交互时预取可能的下一路由 — 关键(导航感知速度提升 200-1000ms) 2.5 使用 React.lazy 在路由边界拆分代码 — 关键(初始打包体积减少 40-70%) 2.6 对重型库使用动态导入 — 关键(从关键路径移除 100-500KB)
-
渲染优化 — 高 3.1 避免在 JSX Props 中创建内联对象 — 高(防止不必要的子组件重渲染) 3.2 对昂贵的派生计算进行防抖 — 高(每次按键节省 50-200ms) 3.3 使用 CSS Containment 隔离布局重算 — 高(布局重算减少 60-90%) 3.4 使用 Children 模式防止父组件重渲染 — 高(消除静态子树的重渲染) 3.5 使用稳定 Key 提升列表渲染性能 — 高(DOM 变更从 O(n) 降至 O(1) 移动) 3.6 使用 TanStack Virtual 虚拟化长列表 — 高(DOM 节点从 O(n) 降至 O(1))
-
数据获取性能 — 高 4.1 在导航或重新获取时中止过期请求 — 高(防止显示过期数据) 4.2 去重相同的进行中请求 — 高(网络请求减少 50-80%) 4.3 消除顺序数据获取瀑布 — 高(页面加载快 2-5 倍) 4.4 在组件挂载前于路由级别预加载数据 — 高(消除 200-1000ms) 4.5 使用 Stale-While-Revalidate 保持缓存新鲜度 — 高(回访用户感知加载 0ms)
-
Core Web Vitals — 中高 5.1 使用 web-vitals 埋点真实用户监控 — 中高(支持数据驱动优化) 5.2 使用响应式尺寸和懒加载优化图片 — 中高(带宽减少 40-70%) 5.3 通过让出优化 Interaction to Next Paint — 中高(INP 从 500ms+ 降至 200ms 以下) 5.4 通过优先级加载优化 Largest Contentful Paint — 中高(LCP 改善 200-1000ms) 5.5 通过尺寸预留防止 Cumulative Layout Shift — 中高(CLS 从 0.25+ 降至 0.1 以下)
-
状态与订阅性能 — 中高 6.1 派生状态而非同步状态以实现零额外渲染 — 中高(消除双重渲染循环) 6.2 将服务端状态与客户端状态管理分离 — 中高(状态管理代码减少 40%) 6.3 拆分 Context 以隔离高频更新 — 中高(重渲染减少 5-50 倍) 6.4 对独立响应式值使用原子状态 — 中高(不必要重渲染减少 3-10 倍) 6.5 使用基于选择器的订阅实现细粒度更新 — 中高(重渲染仅限受影响组件)
-
剖析与度量 — 中 7.1 仅使用生产构建进行基准测试 — 中(防止开发模式开销导致的误报) 7.2 在 CI 中强制执行性能预算 — 中(在合并前捕获 90% 的性能问题) 7.3 优化前先剖析以针对真实瓶颈 — 中(优化效率提升 10 倍) 7.4 阅读火焰图识别热渲染路径 — 中(定位导致 80% 渲染时间的具体函数) 7.5 使用 React Performance Tracks 进行渲染分析 — 中(几分钟内定位渲染瓶颈)
-
内存管理 — 低中 8.1 避免事件处理器中基于闭包的内存泄漏 — 低中(防止 MB 级内存保留) 8.2 卸载时取消异步操作 — 低中(防止过期更新和内存保留) 8.3 清理 Effect 以防止订阅内存泄漏 — 低中(防止线性内存增长) 8.4 在清理函数中释放重型资源 — 低中(防止每个资源保留 5-50MB) 8.5 使用堆快照检测组件保留 — 低中(识别 10-100MB 内存增长)
参考资料
https://react.dev https://react.dev/blog/2025/10/07/react-compiler-1 https://web.dev/articles/vitals https://tanstack.com/virtual https://developer.chrome.com/docs/devtools/performance
相关技能
- React 19 API 最佳实践,参见 react 技能
- Next.js App Router 优化,参见 nextjs-16-app-router 技能
- 客户端表单处理,参见 react-hook-form 技能