SuperAPI AI 工具集

react-performance

编程与开发

查看项目

更新于 10-16 11:30

技能介绍

用途

react-performance 用于指导 React 与 Next.js 的性能优化工作,目标是避免两类常见失败:优化了从来不是瓶颈的地方,以及用可变操作、类型断言或删除测试来换取速度。该技能负责“方法”,具体规则由外部规则目录负责。

主要能力

  • 根据问题类型路由到合适的规则目录,而不是直接套用规则清单。
  • 规定一套可复用的性能工作流程:建立基线、定位开销、一次应用一条规则、复测并保留证据。
  • 明确本仓库的优先规则,当性能建议与不可变性、TDD、类型安全等冲突时,后者优先。
  • 列出常见反模式,帮助识别无效或有害的性能改动。

规则目录路由

在提出改动前,先阅读与问题匹配的目录:

来源 负责内容 适用时机
vercel-react-best-practices(外部,固定版本) 72 条规则,分 8 个按影响排序的类别:async- 瀑布、bundle- 体积、server- RSC/序列化、client- 数据获取、rerender-、rendering-、js-、advanced- 已有测量出的瓶颈,需要具体修复方案时,阅读单个 rules/<id>.md
vercel-composition-patterns(外部,固定版本) 复合组件、布尔属性泛滥、context provider、React 19 API 变化(ref 作为 prop、不再使用 forwardRef) 重渲染或属性透传问题本质是组件 API 问题时
next-best-practices(外部,固定版本) App Router 结构、RSC 边界、异步请求 API、metadata 问题属于 Next.js 语义而非 React 开销时
next-cache-components(外部,固定版本) Cache Components、use cache、重新验证 缓存与重新验证是主要手段时
core-web-vitals、performance(外部,固定版本) 现场 LCP/INP/CLS、非 React 预算、图片、字体、第三方脚本 抱怨的是用户可感知指标而非 React 内部开销时
react-testing、front-end-testing 证明浏览器可观察行为未受影响 性能改动触及渲染输出时
xstate 因分散在 useState 和 useEffect 中而每次按键都重渲染的流程逻辑 重渲染风暴是建模问题而非记忆化问题时

若两个目录冲突,更具体的优先:Next 特定语义优先于通用 React,现场指标指导优先于组件级微开销。

使用方式:方法

1. 建立基线

用用户可观察的术语描述症状——慢路由、无响应输入、沉重首屏——并在改代码前记录一个数字:性能分析、bundle 报告、trace、现场指标。记录测量方式,以便重复。

完成标准:症状、测量方法和起始数字都已写下,且数字可复现。

2. 定位开销

在选择类别前,先找到时间实际花在哪里。目录中的优先顺序是好的搜索顺序——瀑布和 bundle 体积优先,js- 微优化最后——但它是假设生成器,不是诊断。React Profiler、next build 输出、bundle 分析器和网络瀑布是证据;关于重渲染的合理故事不是。

完成标准:主要开销被归因到具体边界——请求瀑布、bundle 入口、序列化负载、重渲染路径、布局或水合步骤——并有归因证据。

3. 一次应用一条规则

阅读具体规则文件,然后只改一处。批量“性能优化”会让复测无法解释,把审查变成猜测。

改动落地前,对照下方仓库规则检查。

完成标准:diff 中恰好一个假设,并指明所应用的规则。

4. 复测并保留证据

重复第 1 步的测量。没有改变数字的改动应回退,而不是“因为是最佳实践”而保留——未测量的优化只有机制没有收益,而 reduce-system-complexity 将增加的机制视为成本。

在 PR 中记录前后对比。性能是非功能保证,因此这个测量就是改动的证据;它不能替代行为测试,行为测试必须保持不变且通过。

完成标准:同一测量在前后均报告,且所有行为测试无需修改仍通过。

仓库规则优先的情况

当通用性能建议与本仓库不妥协的规则冲突时,以下规则优先:

  1. 行为测试不为性能改动而改变。需要编辑断言的性能重构是伪装的行为变更,应走 tdd。删除或弱化测试让基准更好看,绝不在范围内。
  2. 不可变性保持,直到测量另有说明。缓存属性查找、修改累加器或在热循环中复用数组的 js- 规则,仅在已证明的热路径内合法。修改保持在纯函数自身作用域内——绝不修改调用者的数组或共享对象。参见 functional。
  3. 不为速度使用 any 或无理由断言。在信任边界跳过 schema 验证是正确性变更,不是优化。参见 typescript-strict。
  4. 记忆化是挣来的,不是默认。rerender- 规则假设存在测量出的重渲染问题。rerender-simple-expression-in-memo 在目录中正是因为反射式 useMemo/memo 成本高于收益。优先删除原因——渲染期间派生状态、更窄订阅、移动边界——而非添加缓存。
  5. 优先移除机制而非添加。删除瀑布、provider 或 bundle 入口的修复,优于添加缓存、ref 或 memo 且测量效果相同的修复。
  6. Effect 保持建模。如果修复是“再加一个 useEffect 来协调”,流程逻辑需要状态机或派生值,而不是另一个 effect。参见 xstate 和 rerender-derived-state-no-effect。
  7. 第三方规则是固定版本,不是圣旨。外部目录安装在已审查的提交上。当规则与实际使用版本的一手来源(React 或 Next.js 文档)矛盾时,一手来源优先,分歧值得通过 expectations 记录。

适用场景

  • React 或 Next.js 感觉慢:输入时搜索框或列表卡顿、页面打开时持续消耗 CPU、仪表盘迟缓、滚动掉帧、屏幕出现太慢。
  • 怀疑存在 bundle、瀑布、重渲染或水合问题。
  • 审查性能相关 diff。
  • 性能规则似乎与不可变性、TDD 或类型安全指导冲突。

渲染层级决策和浏览器可观察证明参见 front-end-testing 和 react-testing;驱动重渲染的流程逻辑参见 xstate。

反模式

  • 不分析就自上而下套用目录规则——“我们做了 CRITICAL 的”不是诊断。
  • 单个“性能 PR”捆绑二十条规则,无法归因或回退任何单个改动。
  • 反射式给从未测量出重渲染的组件添加 useMemo、useCallback 或 React.memo。
  • 在未并行化的 await 链或 barrel 导入主导 trace 时,却去用 js- 微优化。
  • 以热循环为名修改调用者的数组或共享对象。
  • 为省几毫秒弱化 schema、放宽类型或越过边界断言。
  • 把工作移到客户端让服务端指标好看,或反之,而不测量用户实际感受的指标。
  • 在开发模式或热缓存下测量,并报告为改进。
  • 把 bundle 体积收益当作用户收益,而不检查被移除代码是否在关键路径上。
  • 优化由分散在 effect 中的流程逻辑导致的重渲染风暴,而不是对流程建模。

完成检查

  • 症状是否用用户可观察术语陈述,并有可复现的测量方法?
  • 选择类别前,主要开销是否用证据归因?
  • diff 是否只携带一个假设,并指明所应用的具体规则?
  • 同一测量、同样方式运行,是否显示改进——如果没有,改动是否会被回退?
  • 所有行为测试是否保持不变且通过,没有为适应优化而编辑断言?
  • 每个微优化是否留在已证明的热路径内、作用域局部,且各边界不可变性与类型完整?
  • 在添加缓存前,是否考虑过更简单的修复——删除瀑布、收窄订阅、移动边界?
  • 前后证据是否记录在审查者能看到的地方?

限制

该技能本身不提供具体优化规则,规则由外部固定版本目录提供。资料未提供安装命令、收费或价格信息。