关于 argent-react-native-profiler
面向编码 Agent 的 React Native 性能分析技能,可采集并分析 React 提交和 CPU 活动,也能查询已保存的会话,帮助调查组件开销并关联原生分析数据。
主要功能
- 01采集 React 提交和 CPU 样本
- 02分析高耗时提交与组件开销
- 03查询 CPU 和提交详情
- 04检查组件源码与 fiber 树
- 05重新加载已保存的分析会话
适用场景
- 01定位导致提交缓慢的组件
- 02追踪高耗时组件背后的 CPU 活动
- 03比较修复前后的性能分析会话
- 04将 React 发现与原生性能分析关联
MCP 相关
该技能介绍在基于 MCP 的工作流中使用的性能分析工具,但未说明其提供 MCP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ software-mansion/ argent --skill argent-react-native-profiler安装后在 Claude Code 中输入/argent-react-native-profiler确认已加载。
附带文件references/diagnostic-tools.md
详细介绍
此技能与 argent-react-native-optimization 互为补充,并非替代它。
实体 iPhone:不支持;react-profiler-* 会拒绝 kind: "device"。请在模拟器上进行性能分析。
2. 工具概览
React Profiler(Hermes / React 提交)
| 工具 | 用途 |
|---|---|
react-profiler-start | 开始 CPU 采样并注入 React 提交捕获钩子。可选:sample_interval_us(默认值为 100)。 |
react-profiler-stop | 停止录制;将 cpuProfile 和 commitTree 存储在会话中。 |
react-profiler-status | 仅在流程中途被打断时调用,其他情况绝不调用(调试器断开、Metro 重新加载、暂停、子 Agent 交接或有任何疑虑)。返回 session_status: "active" | "taken_over" | "stopped" | "no_react_runtime"。无副作用。 |
react-profiler-analyze | 运行处理流程并生成报告,其中包含 CPU 数据增强后的热点提交,按 totalRenderMs 降序排列。将原始数据保存到磁盘。 |
react-profiler-component-source | AST 查找:组件的文件、行号、记忆化状态和 50 行源代码。 |
react-profiler-renders | 实时遍历 fiber:每个组件的渲染次数和耗时(无需性能分析会话)。 |
react-profiler-fiber-tree | 实时遍历 fiber:以 JSON 形式返回完整的组件层级结构。 |
深入查询工具(在 analyze 之后调用)
| 工具 | 用途 |
|---|---|
profiler-cpu-query | 定向调查 CPU:顶部函数、按时间窗口筛选的 CPU 数据、调用树、按组件统计的 CPU 数据。 |
profiler-commit-query | 定向调查提交:按组件、时间范围、提交索引或级联树查询。 |
profiler-stack-query | 深入分析 iOS Instruments:卡顿堆栈、函数调用者、线程细分、泄漏详情。 |
profiler-combined-report | React Profiler 和原生性能分析器并行运行时生成交叉关联报告。 |
profiler-load | 列出并重新加载磁盘中之前的性能分析会话,以便使用查询工具重新调查。 |
有关原生性能分析(CPU 热点、UI 卡顿、内存泄漏),请参阅 argent-native-profiler 技能。
3. Agent 行为准则
在整个性能分析工作流中遵循以下规则:
- 并行启动
react-profiler-start和native-profiler-start(在一条消息中发出两个工具调用)。两者都需要device_id;使用相同的 UDID,以便之后关联它们的数据。这样可以获得最佳覆盖范围。 - 如果用户只需要原生性能分析,请使用
argent-native-profiler技能工作流。只有在用户已明确表示本次会话不需要原生性能分析时,才跳过native-profiler-start
分析后:询问下一步
呈现分析报告后,始终询问用户接下来想做什么。提供以下选项:
- 进一步调查:使用查询工具深入分析具体发现(CPU 调用树、提交级联、卡顿堆栈等),在修改前有把握地确定根本原因。
- 实施修复:根据当前发现应用更改,然后重新进行性能分析,衡量指标是否发生变化(有所改善、出现退化或保持不变)。
- 暂时完成:接受当前报告。
不要在报告后默默继续。报告是调查的起点,而不是终点;查询工具正是为了让你深入调查报告中指出的任何问题而存在。
调查期间:主动使用查询工具
深入分析时,根据发现串联调用查询工具:
- 热门提交 → 使用
profiler-commit-query,设置 mode=by_index查看所有组件 → 对最慢的组件使用profiler-cpu-query,设置 mode=component_cpu→ 对热门函数使用profiler-cpu-query,设置 mode=call_tree→ 阅读源文件 → 提出修复方案。 - 内存泄漏 → 使用
profiler-stack-query,设置 mode=leak_stacks,找出相关模块 → 如果可采取行动,则阅读原生源代码。 - 原生卡顿 → 使用
profiler-stack-query,设置 mode=hang_stacks,获取原生调用链 → 与 React 提交时序进行关联。
修复后:始终重新进行性能分析
应用修复后,始终针对同一场景重新进行性能分析。比较修复前后的指标(提交耗时、CPU 时间、渲染次数),并如实报告:目标指标是否有所改善、保持不变或出现退化?是否有其他指标变差?如果需要引用原始数据,请使用 profiler-load 重新加载修复前的会话。如果修复没有带来改善或引入了退化,请明确说明并重新考虑方案。
使用端到端测试确保性能分析可复现
如果性能分析需要特定的交互序列(滚动列表、切换屏幕、触发动画),请在首次运行性能分析前,使用 argent-create-e2e 技能将交互录制为端到端测试。然后在之后的每次运行中重放同一端到端测试。这样可以消除交互差异这一干扰因素,让前后对比更有意义。以下情况尤其重要:
- 即将应用修复后重新进行性能分析(步骤 8)。
- 用户要求比较多个性能分析会话。
- 交互路径超过 2 至 3 个步骤。
4. 标准性能分析工作流
按顺序完成所有步骤;不要中途停止。
步骤 1:开始性能分析
启动会话时,请留意上文提到的 react-native 和 ios-native 分析器选择,并启动相应工具。保存响应中的 startedAtEpochMs:后续计算注释偏移量时需要用到它。本次会话中之后的每次分析器/查询调用都必须使用相同的 device_id。开始之前,与用户共同制定简单的成功标准:最重要的指标是什么(例如 totalRenderMs、特定提交的耗时或某个组件的渲染次数),以及什么阈值才算有意义。这将为后续评估提供依据。成功启动后:
- 如果用户要求你执行性能分析,请根据
argent-device-interact技能中描述的工具,确定如何自行进行分析。 - 如果用户表示希望自己执行交互,请建议其执行何种交互(例如“滚动列表”“切换标签页”),然后等待回复。 如果你收到有关现有性能分析会话由另一个 Agent 所有的信息:
- 如果会话标记为“stale”,你可以直接接手,无需征求用户许可。
- 如果会话未标记为“stale”——在采取行动并终止另一会话之前,请停下来询问用户该怎么做,并说明情况。
为每次交互添加注释
每次调用 gesture-tap 或 gesture-swipe 后,都要使用返回的 timestampMs 记录注释。计算 offsetMs = timestampMs - startedAtEpochMs。每次交互都必须执行此操作,包括返回导航手势,而不仅是主要操作。将收集到的所有注释传递给步骤 3 中的 react-profiler-analyze。
步骤 2:停止并收集数据
并行调用 react-profiler-stop 和 native-profiler-stop。只有在步骤 1 中未启动 native-profiler-stop 的情况下,才可跳过它。记下 duration_ms 和 fiber_renders_captured。
如果 fiber_renders_captured: 0,请提醒用户:React 提交数据可能缺失。
步骤 3:分析
调用 react-profiler-analyze,并传入 port、device_id、project_root、platform 和 rn_version。报告包含 reactCompilerEnabled、strictModeEnabled 和 buildMode 等元数据;请检查返回的 Markdown 报告中的这些信息。
如果你使用 gesture-tap/gesture-swipe 执行了交互,请传入 annotations,以标记每项操作发生的时间。每条注释的 offsetMs 必须按 tapTimestampMs - startedAtEpochMs 计算,其中 tapTimestampMs 是 gesture-tap/gesture-swipe 工具返回的 timestampMs,而 startedAtEpochMs 是 react-profiler-start 返回的值。计算时不要使用 Date.now();只能使用工具返回的服务端时间戳。
如果同时运行了两种分析器,还要调用 native-profiler-analyze,然后必须调用 profiler-combined-report 生成交叉关联视图;两种分析器都运行时,不得跳过此步骤。综合报告能揭示单独报告无法发现的关联。
分析报告包含每次提交的 CPU 热点,可准确显示每次缓慢的 React 提交期间运行了哪些 JS 函数。原始数据会自动保存到磁盘,以便之后重新加载。
步骤 4:评估结果
分析结果是否能准确反映应用的问题——不要假设性能总会提升;应结合 react-native 的工作原理,验证结果是否合理。请确保反馈真实可信,并准备好在需要时调整分析方法。
步骤 5:展示结果并询问后续步骤
简要总结关键发现——说明是否存在优化空间,以及进一步操作可能如何影响性能。然后遵循“分析后”指南:询问用户是要进一步调查、实施修复(如果可行),还是停止。
步骤 6:深入调查(迭代进行)
根据报告中的发现,使用查询工具进行深入调查:
- 组件运行缓慢? ->
profiler-cpu-querymode=component_cpucomponent_name=AppNavigator:显示该组件提交期间运行的 JS 函数。 - 想查看调用树? ->
profiler-cpu-querymode=call_treefunction_name=expensiveFunction:显示调用方和被调用方。 - 某个时间段内发生了什么? ->
profiler-commit-querymode=by_time_range:列出时间范围内的所有提交。 - 查看完整提交详情? ->
profiler-commit-querymode=by_indexcommit_index=38:显示所有组件、props 变更和父级级联。 - 是谁触发了谁? ->
profiler-commit-querymode=cascade_tree:显示可视化的父子级联关系。 - iOS 卡顿详情? ->
profiler-stack-querymode=hang_stacks:显示卡顿期间的原生调用堆栈。
按需重复调查,直到找到根因函数和文件;诚实评估请参阅步骤 4。每轮调查后,询问用户是想继续深入排查还是转而修复。
步骤 7:重新加载之前的会话
如果你对多个场景进行了性能分析,并需要重新查看之前的数据:
- 调用
profiler-loadmode=list,查看所有已保存会话及其时间戳(列表现在还会显示 Runtime / Device / Metro bundle 列,帮助识别正确的会话)。 - 调用
profiler-loadmode=load_reactsession_id=<timestamp>device_id=<UDID>,重新加载 React 数据。device_id会将重新加载的数据限定在port:device_id缓存槽中。 - 调用
profiler-loadmode=load_nativesession_id=<timestamp>device_id=<UDID>,重新加载原生性能分析器数据。 - 查询工具现在会使用重新加载的会话数据;请传入相同的
device_id,否则将无法命中缓存。
这适用于修复前后对比:进行性能分析、修复、再次分析,然后重新加载原始会话,逐项比较指标。
步骤 8:应用修复并重新进行性能分析
如果有可用的修复,请使用 react-profiler-component-source 或 Read 工具阅读已识别瓶颈的源代码。应用修复后,重新进行性能分析(步骤 1 -> 用户交互 -> 步骤 2 -> 步骤 3 -> 步骤 4)。报告目标指标是有所改善、保持不变还是退步。还要检查修复是否导致其他指标退步(例如,渲染次数减少但 CPU 时间增加,或现在有其他组件重新渲染得更多)。如果修复没有带来净收益,或权衡结果无法接受,请撤销并重新考虑。
提示: 如果交互序列是通过端到端测试记录的(参见上文“使用端到端测试进行可复现的性能分析”),请使用 e2e-execute 重放,而不是手动重复这些步骤。这样可以确保比较时的交互条件完全一致。如果端到端测试在重放过程中失败(例如,UI 修复改变了布局),请按照 argent-create-e2e 的 诊断重放失败 修复端到端测试,然后重试性能分析流程。
如果用户表示不希望进行任何更改,请提供性能分析报告并跳过修复,但应向用户提出修复建议。
React Compiler 规则: 如果分析报告表明已启用 React Compiler,除非确认编译器回退了该组件的优化(检查 react-profiler-fiber-tree,确认该组件上不存在 useMemoCache),否则不要建议使用 useCallback/useMemo/React.memo。
5. 重要注意事项
- 开发模式耗时增加:
buildMode: "dev"下的渲染速度约为生产模式的 1/3。优先关注较高的normalizedRenderCount;该指标可映射到生产模式。 - 修复后重新运行:更改后务必重新进行性能分析。应如实说明指标是改善、退步还是持平;不要想当然地认为有所改善。
excluded仅供参考:animatedSubtrees和recyclerChildren中的组件按设计会重新渲染。- Strict Mode:会重复调用渲染。检测到 Strict Mode 后,流水线会自动将
normalizedRenderCount减半。 - 调试器连接:如果连接中断,已启动的性能分析也会关闭。尝试恢复之前,请调用
react-profiler-status:该工具会告知会话状态为active、taken_over、stopped或no_react_runtime,以便你判断应先停止、重启还是重新连接。 - 需要留意的干扰因素:
- 不同运行中的实时 API 数据可能有所差异(例如载荷大小和内容数量不同),这会独立于修复本身影响渲染次数和耗时。若依赖数据的组件存在波动,请予以说明。
- 性能分析器的开销会抬高 CPU 测量值。如果 iOS Instruments 显示
JSLexer、JSONEmitter或 Hermes 内部模块占用了大量 JS 线程,这反映的是性能分析器的检测开销,而非应用本身的工作。请忽略这些条目。 - 运行结果并非完全可复现。提交耗时出现小幅波动(低于约 10-15%)可能只是噪声;只有持续且方向一致的变化才能作为信号。
独立诊断工具(实时渲染统计、fiber 树、CPU 摘要)请参阅 references/diagnostic-tools.md。