mcpField
A
argent-react-native-profiler

argent-react-native-profiler

github.com/software-mansion开发3.1k27.1k 次安装今天更新
代码仓库

关于 argent-react-native-profiler

面向编码 Agent 的 React Native 性能分析技能,可采集并分析 React 提交和 CPU 活动,也能查询已保存的会话,帮助调查组件开销并关联原生分析数据。

主要功能

  1. 01采集 React 提交和 CPU 样本
  2. 02分析高耗时提交与组件开销
  3. 03查询 CPU 和提交详情
  4. 04检查组件源码与 fiber 树
  5. 05重新加载已保存的分析会话

适用场景

  1. 01定位导致提交缓慢的组件
  2. 02追踪高耗时组件背后的 CPU 活动
  3. 03比较修复前后的性能分析会话
  4. 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-sourceAST 查找:组件的文件、行号、记忆化状态和 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-reportReact 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
分析后:询问下一步

呈现分析报告后,始终询问用户接下来想做什么。提供以下选项:

  1. 进一步调查:使用查询工具深入分析具体发现(CPU 调用树、提交级联、卡顿堆栈等),在修改前有把握地确定根本原因。
  2. 实施修复:根据当前发现应用更改,然后重新进行性能分析,衡量指标是否发生变化(有所改善、出现退化或保持不变)。
  3. 暂时完成:接受当前报告。

不要在报告后默默继续。报告是调查的起点,而不是终点;查询工具正是为了让你深入调查报告中指出的任何问题而存在。

调查期间:主动使用查询工具

深入分析时,根据发现串联调用查询工具:

  • 热门提交 → 使用 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-query mode=component_cpu component_name=AppNavigator:显示该组件提交期间运行的 JS 函数。
  • 想查看调用树? -> profiler-cpu-query mode=call_tree function_name=expensiveFunction:显示调用方和被调用方。
  • 某个时间段内发生了什么? -> profiler-commit-query mode=by_time_range:列出时间范围内的所有提交。
  • 查看完整提交详情? -> profiler-commit-query mode=by_index commit_index=38:显示所有组件、props 变更和父级级联。
  • 是谁触发了谁? -> profiler-commit-query mode=cascade_tree:显示可视化的父子级联关系。
  • iOS 卡顿详情? -> profiler-stack-query mode=hang_stacks:显示卡顿期间的原生调用堆栈。

按需重复调查,直到找到根因函数和文件;诚实评估请参阅步骤 4。每轮调查后,询问用户是想继续深入排查还是转而修复。

步骤 7:重新加载之前的会话

如果你对多个场景进行了性能分析,并需要重新查看之前的数据:

  1. 调用 profiler-load mode=list,查看所有已保存会话及其时间戳(列表现在还会显示 Runtime / Device / Metro bundle 列,帮助识别正确的会话)。
  2. 调用 profiler-load mode=load_react session_id=<timestamp> device_id=<UDID>,重新加载 React 数据。device_id 会将重新加载的数据限定在 port:device_id 缓存槽中。
  3. 调用 profiler-load mode=load_native session_id=<timestamp> device_id=<UDID>,重新加载原生性能分析器数据。
  4. 查询工具现在会使用重新加载的会话数据;请传入相同的 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。

评论

支持 Markdown