性能与内存
页面检查可以确认一次操作改变了什么;Trace 则记录这段过程里各线程执行了什么、花了多久,以及内存如何变化。agent-lynx 把采集、文件校验和本地查询交给 CLI,把分析方法交给对应的 skills。
下面继续使用 Tailwind CSS 的 Settings 页面。示例已完成应用连接,$CLIENT_ID 指选定的应用;bundle 已在本地构建,URL 可由设备访问。应用需要支持相应的 Trace 采集能力。
录制包含内存数据的加载 Trace
采集的起止位置决定能回答哪些问题。为了覆盖首次渲染,agent 先加载 lynx-trace-record,在打开页面之前开始录制,再检查产物是否包含加载事件和内存配置。
帮我录一份 Settings 页面加载的性能 Trace,把内存数据也带上,并确认这份数据能用于分析。
思路:先查找采集 skill,确认录制顺序和内存选项,再打开页面。
agent-lynx skills list找到采集与分析指南
# 发现采集和分析 skill;这里只节选相关条目。
agent-lynx skills list<available_skills>
<skill>
<name>lynx-trace-analysis</name>
<description>Specializes in analyzing Lynx trace data to diagnose performance issues and provide actionable optimization strategies.
Key Scenarios:
- Loading Performance: Diagnosing slow startup metrics (FCP, FMP, TTI) and white screen issues.
- Smoothness Analysis: Investigating root causes for scroll jank, frame drops, and interaction lag.
- Regression Detection: Comparing traces to identify performance degradation or verify optimization gains between versions.
- Pipeline Deep Dive: Pinpointing bottlenecks in specific rendering stages like Layout, Paint, JS execution, and background threads.
- Native Module Analysis: Investigating performance issues related to native module calls.
- Memory Analysis: Diagnosing high PSS, page lifecycle leaks, shared BTS context growth, VM pool waste, and JS heap snapshots.</description>
<location>/tmp/agent-lynx-perf-docs-20261030/node_modules/@lynx-js/skill-lynx-trace-analysis/SKILL.md</location>
</skill>
<skill>
<name>lynx-trace-record</name>
<description>This guide provides step-by-step instructions for recording Lynx performance traces. Use this guide when the user asks how to record a trace.</description>
<location>/tmp/agent-lynx-perf-docs-20261030/node_modules/@lynx-js/skill-lynx-trace-record/SKILL.md</location>
</skill>
</available_skills>agent-lynx skills get lynx-trace-record确认采集顺序
# 节选先录制后打开页面的规则,以及内存与 GC 选项;执行入口使用当前 CLI 的 trace 命令。
agent-lynx skills get lynx-trace-record### Step 2. Start recording:
Execute the start command **BEFORE** building or opening the page on your device. This ensures you capture the entire first frame of the page. Use the `--client` parameter with the client ID from Step 1.
…
| Enable memory data collection | `--enable-memory-trace` | `enableMemoryTrace` | `false` |
| Disable automatic Garbage Collection | `--no-force-gc` | `forceGC` | `true` |
Skill directory: /tmp/agent-lynx-perf-docs-20261030/node_modules/@lynx-js/skill-lynx-trace-recordagent-lynx trace start --enable-memory-trace已开启内存采集
# 在页面加载前开始采集,显式开启内存数据;自动 GC 保持默认开启。
agent-lynx trace start --client "$CLIENT_ID" --enable-memory-trace{
"success": true,
"started": true,
"restartRequired": false,
"message": "Tracing started successfully. Open the target page and perform the actions to capture."
}agent-lynx open页面已打开
# 打开本地构建的 Settings bundle;从响应中提取页面列表。
agent-lynx open 'http://127.0.0.1:33227/main.lynx.bundle?fullscreen=true' --client "$CLIENT_ID" | jq '.data.data'[
{
"session_id": 1,
"type": "",
"url": "http://127.0.0.1:33227/main.lynx.bundle?fullscreen=true"
}
]agent-lynx wait --text Settings页面已显示
# 确认目标页面已经显示,再结束本次加载采集。
agent-lynx wait --text Settings --client "$CLIENT_ID" --session 1Matched text "Settings" after 296ms. A fresh snapshot was cached.agent-lynx trace end未报告数据丢失
# 使用同一 client 停止采集,保留下载句柄,并检查是否丢失数据。
agent-lynx trace end --client "$CLIENT_ID"{
"success": true,
"message": "Tracing completed successfully. Download the stream with `agent-lynx trace read-data`.",
"stream": "1",
"dataLossOccurred": false
}agent-lynx trace read-data已保存 .pftrace
# 把刚返回的 stream 1 保存到本地;下载完成后即可脱离设备分析。
agent-lynx trace read-data --client "$CLIENT_ID" --stream 1 -o ./settings-memory.pftrace{
"success": true,
"message": "Trace data saved successfully.",
"filePath": "/tmp/agent-lynx-perf-docs-20261030/settings-memory.pftrace",
"bytesWritten": 154691
}思路:文件已经下载。接下来检查能否解析,以及页面加载事件和内存开关是否真的写进了 Trace。
agent-lynx trace event-summary8,257 条事件
# 解析本地文件;用 jq 隐去完整事件清单,保留计数和文件标识。
agent-lynx trace event-summary ./settings-memory.pftrace --json | jq 'del(.events)'{
"success": true,
"parseSucceeded": true,
"trace": {
"path": "/tmp/agent-lynx-perf-docs-20261030/settings-memory.pftrace",
"bytes": 154691,
"sha256": "383b14aaf6e08522eb13969c859a6154c2e0fbebcafeaeca5d6247523edee2e7"
},
"eventSource": "slice.name",
"totalEvents": 8257,
"uniqueEventNames": 889
}agent-lynx trace query加载与内存配置已核对
# 核对加载、DOM 就绪事件,以及 TRACE_BEGIN 中实际记录的内存和 GC 配置。 用 jq 将校验结果显示为紧凑文本。
agent-lynx trace query ./settings-memory.pftrace --sql "SELECT name AS evidence, CAST(COUNT(*) AS TEXT) AS value FROM slice WHERE name IN ('LynxLoadTemplate', 'LynxDomReady') GROUP BY name UNION ALL SELECT a.key, a.display_value FROM slice s JOIN args a ON a.arg_set_id = s.arg_set_id WHERE s.name = 'TRACE_BEGIN'" | jq -r '"parseSucceeded: \(.parseSucceeded), truncated: \(.truncated)", (.rows[] | "\(.evidence): \(.value)")'parseSucceeded: true, truncated: false
LynxDomReady: 1
LynxLoadTemplate: 1
debug.enable_memory_trace: 1
debug.memory_trace_force_gc: 1已保存 settings-memory.pftrace,解析得到 8,257 条事件、889 种事件名,采集未报告数据丢失。文件包含 LynxLoadTemplate 和 LynxDomReady,内存采集与自动 GC 的记录值均为 1。
这份 Trace 可以继续用于查看本次页面加载和内存变化;下一步可以加载分析 skill,针对具体问题读取对应指南。
trace end 返回的 stream 属于本次采集,需要在同一个 client 上用 trace read-data 下载;完成后,event-summary、query 和分析脚本都可以离线运行。如果 trace start 返回 restartRequired: true,应重启应用、重新确认 client 并再次开始采集,直到 started: true 后再打开页面。
--enable-memory-trace 用于请求运行时输出内存数据。除了确认参数,还要核对文件中的配置和实际数据;旧运行时可能缺少所需轨道。--force-gc 默认开启,会影响内存曲线;需要观察自然 GC 行为时可用 --no-force-gc,并在比较结果时保持采集条件一致。
让分析 skill 接着处理这份 Trace
采集成功之后,问题决定分析路径:首帧耗时对应 metrics 与渲染流水线指南,滚动卡顿对应 jank 指南,内存变化对应 memory 指南。下面沿用刚保存的文件,让 lynx-trace-analysis 生成 Settings 页面的内存报告。
用这份 Trace 看一下 Settings 页面加载期间的内存情况,给我一份能继续查看的报告。
思路:已有可解析的 Trace,直接加载分析 skill,并选择它的内存分析指南。
agent-lynx skills get lynx-trace-analysis选择内存分析指南
# 节选分析指南目录;根据问题选择 memory-analysis。
agent-lynx skills get lynx-trace-analysis### KNOWLEDGE BASE
*These are the "Guidebooks" you must load to know **what** to query.*
- [metrics-analysis](./references/metrics-analysis.md): Guide for: Startup phases, FCP/TTI, Navigation timing, White screen causes.
- [timing-flag](./references/timing-flag.md): Guide for Diagnosing missing performance callbacks, invalid timing flags, and abnormal ActualFMP/FMP durations.
- [jank-analysis](./references/jank-analysis.md): Guide for: Scroll smoothness, Input latency, Long Tasks (>16ms), Frame drops.
- [diff-analysis](./references/diff-analysis.md): Guide for: Comparing two traces, identifying regressions in specific phases.
- [nativemodule-analysis](./references/nativemodule-analysis.md): Guide for: Bridge communication, Native method latency, Serialization costs.
- [render-pipeline](./references/render-pipeline.md): Guide for: Understanding Lynx rendering pipeline, identifying slow stages, and analyzing gaps between metrics.
- [event-analysis](./references/event-analysis.md): Guide for: Diagnosing missing touch/custom/global events, tracing event dispatch to the real business handler, and distinguishing event delivery delay from handler cost.
- [memory-analysis](./references/memory-analysis.md): Guide for: High memory, page load/exit memory changes, memory leaks, shared BTS contexts, scrolling trends, VM pools, and JS heap snapshots.
- [sql-guide](./references/sql-guide.md): Guide for writing raw SQL queries to query trace data.
- [sourcemap-remapping](./references/sourcemap-remapping.md): Guide for remapping line and column numbers from Lynx trace event arguments back to original source positions.
…
Skill directory: /tmp/agent-lynx-perf-docs-20261030/node_modules/@lynx-js/skill-lynx-trace-analysisRead · references/memory-analysis.md按页面选择分析范围
// 读取 skill 返回目录中的内存指南;这里节选分析入口和报告命令。
Read $TRACE_SKILL_DIR/references/memory-analysis.md## First Action
Classify the request, then perform exactly one first action:
| Request | First action |
|---|---|
| Broad memory analysis, high memory, leak check, page load/exit memory | Run `memory-analysis` with the trace path |
| Specific page URL | Run `memory-analysis --url "<substring>"` |
| Specific `instance_id` | Run `memory-analysis --instance-id <id>` |
| Scrolling/sliding trend | Ensure page URL or `instance_id` and an absolute trace time range are known, then run `memory-analysis --scenario scroll --start <ms> --end <ms>` |
| Specific VM snapshot numbers | Run `memory-analysis` first to obtain the VM's 1-based snapshot list |
Do not ask follow-up questions for a broad memory request. The default analysis covers every page created
after trace recording starts.
## Main Analysis Command
```bash
node <path_to_the_skill>/scripts/trace_query.bundle.cjs memory-analysis \
--path "<trace_path_or_url>" \
--output "<report_path>.html"
```node · trace_query.bundle.cjs memory-analysis报告已生成
# TRACE_SKILL_DIR 是 skills get 返回的目录。按 bundle URL 选择页面,生成 HTML 报告;这里节选报告路径、摘要和警告。
node "$TRACE_SKILL_DIR/scripts/trace_query.bundle.cjs" memory-analysis --path ./settings-memory.pftrace --url main.lynx.bundle --output ./settings-memory-report.htmlMemory analysis: {
"valid": true,
"reportPath": "/tmp/agent-lynx-perf-docs-20261030/settings-memory-report.html",
"summary": {
"analyzedPageCount": 1,
"issueCount": 0,
"conclusion": "未发现规则命中的高或中置信度内存问题,请结合 HTML 报告检查完整数据。"
},
"warnings": []
}
…已生成 settings-memory-report.html,其中包含页面与 VM 的内存数据和交互图表。本次选中的页面在采集窗口内未命中规则定义的高或中置信度内存问题。
这次录制覆盖了页面加载,没有覆盖退出后的释放过程;要判断页面关闭后是否仍有对象存活,需要补充完整生命周期的采集。
这里的 $TRACE_SKILL_DIR 来自 skills get 返回的 Skill directory。分析脚本随 skill 提供;agent 先读取指南,再选择分析入口。报告路径可以继续交给人查看,后续查询也可以复用同一份 Trace。
查看当前内存并保存 JS 堆快照
如果问题是“当前哪些部分占用内存”,可以直接查询存活实例,无需重新录制 Trace。下面这段独立对话检查 Settings 页面的即时占用,再保存两个 VM 的堆快照:全局查询使用 session -1,抓取对象图则使用已选中的页面 session 2。
现在 Settings 页面主要占用哪些内存?把后台和主线程的 JS 堆快照也保存下来,留作后续检查。
思路:先读取全局内存,区分运行时、元素和视图占用,再保存两个 VM 的对象快照。
agent-lynx skills get lynx-devtool确认查询范围
# 节选全局内存与 JS 堆快照操作;全局统计和页面 VM 使用不同的 session 范围。
agent-lynx skills get lynx-devtool#### 15. Take Heap Snapshot
Capture a QuickJS heap snapshot from the current Lynx session and save it as a `.heapsnapshot` file.
```bash
agent-lynx take-heap-snapshot [options]
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: (Optional) Session ID.
- `--thread <thread>`: (Optional) Target VM thread, `background` or `main`. Defaults to `background`.
- `-o, --output <path>`: (Optional) Output file path. Defaults to the OS temp directory.
#### 16. Query Global Memory Usage
Query Lynx global memory usage through the global `Memory.*` CDP domain. Use the generic `cdp` command and send the request to the global DevTool handler with session ID `-1`.
```bash
# Get global Lynx memory usage across live instances
agent-lynx cdp -s -1 -m Memory.getAllMemoryUsage
agent-lynx cdp -s -1 -m Memory.getAllMemoryUsage '{"timeoutMs":50000}'
```
- `-c, --client <clientId>`: (Optional) Client ID.
- `-s, --session <sessionId>`: CDP session ID. Use `-1` for the global DevTool handler unless you have a platform-specific reason to override it.
- `params.timeoutMs` (Optional): Non-negative timeout in milliseconds. Maximum value is `300000`.
The command prints the raw `Memory.getAllMemoryUsage` JSON. Do not expect the CLI output to contain derived `summary`, `topMemoryItems`, or `topInstances` wrapper fields.
When the DevTool MCP server is available, prefer the `Memory_getAllMemoryUsage` MCP tool for the same raw payload instead of shelling out to the CLI.
…
Skill directory: /tmp/agent-lynx-perf-docs-20261030/node_modules/@lynx-js/skill-lynx-devtoolRead · Memory.getAllMemoryUsage.md全局 session -1
// 读取支持的 CDP 方法说明,确认全局 session -1 和 timeoutMs 参数。
Read $DEVTOOL_SKILL_DIR/references/cdp/memory/Memory.getAllMemoryUsage.md# Memory.getAllMemoryUsage
Scope: This is a Lynx global CDP extension. Send it to the global DevTool handler with session ID `-1` unless you have a platform-specific reason to override the session.
- `Memory.getAllMemoryUsage` - Get global Lynx memory usage across live registered Lynx instances.
- Input:
- `timeoutMs` (integer, optional): Non-negative timeout in milliseconds. `0` or omission lets the platform choose its default wait policy. Maximum accepted value is `300000`; fractional values are rejected.agent-lynx cdp --method Memory.getAllMemoryUsage1/1 实例,7.85 MiB
# 查询整个应用中已注册的 Lynx 实例;jq 节选全局总量与内存构成,并保留采集完成状态。
agent-lynx cdp --client "$CLIENT_ID" --session -1 --method Memory.getAllMemoryUsage '{"timeoutMs":50000}' | jq '{collectionStatus, completedInstanceCount, expectedInstanceCount, totalBytes, appBytes, ratioToApp, elementNodeCount, elementBytes, viewBytes, mainThreadRuntimeBytes, backgroundThreadRuntimeBytes}'{
"collectionStatus": "completed",
"completedInstanceCount": 1,
"expectedInstanceCount": 1,
"totalBytes": 8229400,
"appBytes": 128318464,
"ratioToApp": 0.06413262552768711,
"elementNodeCount": 81,
"elementBytes": 86832,
"viewBytes": 0,
"mainThreadRuntimeBytes": 599976,
"backgroundThreadRuntimeBytes": 7542592
}思路:这次返回的主要占用是后台运行时。接下来的堆快照切回 Settings 页面的 session 2,分别采集两个线程。
agent-lynx take-heap-snapshot --thread background后台堆快照已保存
# 保存后台 VM 的 JS 对象图,供后续检查对象类型和引用链。
agent-lynx take-heap-snapshot --client "$CLIENT_ID" --session 2 --thread background -o ./settings-background.heapsnapshotHeap snapshot saved to ./settings-background.heapsnapshotagent-lynx take-heap-snapshot --thread main主线程堆快照已保存
# 另存主线程 VM 快照;两个文件对应同一页面的不同运行时。
agent-lynx take-heap-snapshot --client "$CLIENT_ID" --session 2 --thread main -o ./settings-main.heapsnapshotHeap snapshot saved to ./settings-main.heapsnapshot本次采集完成了 1/1 个实例:Lynx 归属内存为 7.85 MiB,约占应用 122.37 MiB 占用的 6.41%。主要来自后台运行时 7.19 MiB;主线程运行时为 585.91 KiB,元素树为 84.80 KiB,共 81 个元素节点。这次运行时返回的 viewBytes 为 0。
已保存 settings-background.heapsnapshot 和 settings-main.heapsnapshot。它们可以用于检查 JS 对象和引用链;单次占用和单份快照还不能证明内存泄漏。
全局返回的 totalBytes 是 Lynx 归属内存,appBytes 是应用占用;共享后台运行时会在全局总量中去重。堆快照只描述选定 VM 的 JS 对象,与全局统计的范围不同。比较快照时,应保持同一 VM、相同 GC 条件,并记录加载、操作和退出等生命周期位置。
性能与内存能力
命令参数参见 CLI 参考,内存字段参见 Memory 域。需要把页面运行时状态保存为可回放文件时,使用 Recorder。