React Best Practices技能使用说明
2026-03-29
新闻来源:网淘吧
围观:11
电脑广告
手机广告
React 最佳实践
来自 Vercel 工程团队的 React 和 Next.js 应用程序综合性能优化指南。包含 8 个类别下的 57 条规则,按影响程度排序。
安装
OpenClaw / Moltbot / Clawbot
npx clawhub@latest install react-best-practices
此技能的作用
为以下方面提供可操作的规则:
- 消除请求瀑布流
- 优化打包体积
- 提升服务器端性能
- 高效的客户端数据获取
- 最小化重新渲染
- 渲染性能优化
- JavaScript 微优化
- 针对边缘情况的高级模式
何时使用
- 编写新的 React 组件或 Next.js 页面时
- 实现数据获取时(客户端或服务器端)
- 审查代码以查找性能问题时
- 重构 React/Next.js 应用程序时
- 优化打包体积或加载时间时
- 调试缓慢渲染或瀑布流问题
关键词
React性能、Next.js优化、包体积、瀑布流、Suspense、服务器组件、RSC、重新渲染、useMemo、动态导入、并行获取、缓存、SWR
按优先级划分的规则类别
| 优先级 | 类别 | 影响程度 | 规则前缀 |
|---|---|---|---|
| 1 | 消除瀑布流 | 关键 | async- |
| 2 | 包体积优化 | 关键 | bundle- |
| 3 | 服务器端性能 | 高 | server- |
| 4 | 客户端数据获取 | 中高 | client- |
| 5 | 重渲染优化 | 中等 | rerender- |
| 6 | 渲染性能 | 中等 | rendering- |
| 7 | JavaScript 性能 | 低-中等 | js- |
| 8 | 高级模式 | 低 | advanced- |
快速参考
1. 消除瀑布流(关键)
| 规则 | 描述 |
|---|---|
async-defer-await | 将 await 移至实际使用的分支中 |
async-parallel | 使用Promise.all()处理独立操作 |
异步依赖 | 对部分依赖使用更好的方式 |
异步API路由 | 在API路由中尽早启动Promise,稍后等待 |
异步Suspense边界 | 使用Suspense流式传输内容 |
2. 打包体积优化(关键)
| 规则 | 描述 |
|---|---|
打包-桶式导入 | 直接导入,避免使用桶文件 |
打包-动态导入 | 使用next/dynamic处理重量级组件 |
打包-延迟第三方 | 在页面水合后加载分析/日志记录 |
打包-条件加载 | 仅在功能激活时加载模块 |
打包-预加载 | 在悬停/聚焦时预加载以提升感知速度 |
3. 服务器端性能(高优先级)
| 规则 | 描述 |
|---|---|
服务器认证操作 | 对API路由等服务器操作进行身份验证 |
服务器缓存-React | 使用React.cache()进行请求级去重 |
服务器缓存-LRU | 使用LRU缓存实现跨请求缓存 |
服务器去重-属性 | 避免RSC属性中的重复序列化 |
服务器序列化 | 最小化传递给客户端组件的数据 |
服务器并行获取 | 重构组件以实现并行数据获取 |
服务器非阻塞后处理 | 使用after()进行非阻塞操作 |
4. 客户端数据获取(中高优先级)
| 规则 | 描述 |
|---|---|
客户端-SWR-去重 | 使用 SWR 实现自动请求去重 |
客户端-事件监听器 | 去重全局事件监听器 |
客户端-被动事件监听器 | 为滚动事件使用被动监听器 |
客户端-本地存储架构 | 版本化并最小化 localStorage 数据 |
5. 重新渲染优化(中等难度)
| 规则 | 描述 |
|---|---|
重新渲染-延迟读取 | 不要订阅仅用于回调的状态 |
重新渲染-记忆化 | 将耗时工作提取到记忆化组件中 |
重新渲染-带默认值的记忆化 | 提升默认非原始属性 |
重新渲染-依赖项 | 在副作用中使用原始依赖项 |
重新渲染-派生状态 | 订阅派生布尔值,而非原始值 |
在渲染时派生状态,而非在副作用中 | rerender-functional-setstate |
使用函数式setState以获得稳定的回调 | rerender-lazy-state-init |
对于开销较大的值,向useState传递函数 | rerender-simple-expression-in-memo |
避免对简单原始值使用memo | rerender-move-effect-to-event |
将交互逻辑放在事件处理器中 | rerender-transitions |
使用startTransition处理非紧急更新 | rerender-use-ref-transient-values |
使用ref处理频繁变化的临时值 | 6. 渲染性能(中等) |
规则
| 描述 | rendering-animate-svg-wrapper |
|---|---|
动画化div包装器,而非SVG元素 | rendering-content-visibility |
对长列表使用content-visibility | Use content-visibility for long lists |
渲染提升JSX | 将静态JSX提取到组件外部 |
渲染SVG精度 | 降低SVG坐标精度 |
渲染水合无闪烁 | 对仅客户端数据使用内联脚本 |
渲染水合抑制警告 | 抑制预期的不匹配 |
渲染活动 | 使用Activity组件控制显示/隐藏 |
渲染条件渲染 | 条件判断使用三元运算符,而非&& |
渲染使用过渡加载 | 加载状态优先使用useTransition |
7. JavaScript性能(低-中)
| 规则 | 描述 |
|---|---|
JS批量DOM CSS | 通过类或cssText分组CSS更改 |
JS索引映射 | 为重复查找构建Map |
JS缓存属性访问 | 在循环中缓存对象属性 |
js-缓存函数结果 | 在模块级Map中缓存函数结果 |
js-缓存存储 | 缓存localStorage/sessionStorage读取 |
js-合并迭代 | 将多个filter/map合并到单个循环中 |
js-优先检查长度 | 在执行高开销操作前检查数组长度 |
js-提前退出 | 从函数中提前返回 |
js-提升正则表达式 | 将正则表达式创建提升到循环外部 |
js-最小最大值循环 | 使用循环求最小/最大值而非排序 |
js-集合映射查找 | 使用Set/Map实现O(1)复杂度查找 |
js-不可变排序 | 使用toSorted()实现不可变性 |
8. 高级模式(低优先级)
| 规则 | 描述 |
|---|---|
高级事件处理程序引用 | 将事件处理程序存储在引用中 |
高级单次初始化 | 每次应用加载时仅初始化一次 |
高级使用最新值 | useLatest 用于稳定的回调引用 |
使用方法
阅读单个规则
每个规则文件位于rules/目录下,包含:
- 简要说明其重要性
- 错误代码示例及解释
- 正确代码示例及解释
- 附加上下文和参考资料
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/rerender-memo.md
完整编译文档
如需包含所有规则详情的完整指南:AGENTS.md
这份2900多行的文档包含每个规则的完整代码示例和详细解释,适合全面参考。
关键模式
并行数据获取
// Bad: sequential
const user = await fetchUser()
const posts = await fetchPosts()
// Good: parallel
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
])
动态导入
// Bad: bundles Monaco with main chunk
import { MonacoEditor } from './monaco-editor'
// Good: loads on demand
const MonacoEditor = dynamic(
() => import('./monaco-editor').then(m => m.MonacoEditor),
{ ssr: false }
)
函数式 setState
// Bad: stale closure risk
const addItem = useCallback((item) => {
setItems([...items, item])
}, [items]) // recreates on every items change
// Good: always uses latest state
const addItem = useCallback((item) => {
setItems(curr => [...curr, item])
}, []) // stable reference
切勿
- 切勿对可并行运行的操作顺序使用 await
- 切勿从桶文件导入(
import { X } from 'lib')——应直接导入 - 切勿在服务器操作中跳过身份验证——应将其视为 API 路由
- 切勿向客户端组件传递整个对象,当仅需一个字段时
- 切勿
使用 &&对数字进行条件渲染——应使用三元运算符 - 切勿订阅仅用于事件处理程序的状态——应按需读取
- 切勿使用
.sort()对数组进行原地排序——应使用.toSorted() - 切勿将初始化操作
置于useEffect([])中——请改用模块级守卫
文章底部电脑广告
手机广告位-内容正文底部


微信扫一扫,打赏作者吧~