Skip to content
阅读进度

Agent 页面卡顿、启动慢或 ANR,怎样沿链路定位? ​

返回 性能与稳定性 目录

标准回答 ​

我会先区分现象:启动慢是页面或内容迟迟没出现,卡顿是交互帧没有按时完成,ANR 是某类关键响应超过系统允许时间。模型回答慢也可能只是网络或推理等待,不能看到等待动画就判断主线程卡住。

对 Agent 请求,我会把时间拆成用户提交、上下文准备、模型首个输出、工具开始和结束、UI 更新,以及最终任务完成。用同一个任务标识对齐日志和 trace,先确定延迟主要发生在哪段。端到端慢不一定靠优化 View 就能解决。

如果 UI 本身失去响应,我会看 ANR 原因和各线程栈,再用 Perfetto 看主线程在运行、等待锁、同步 Binder 调用,还是已经可运行却迟迟没被调度。锁等待继续找持锁线程,Binder 等待继续看服务端;渲染问题则沿 Choreographer、measure/layout/draw、RenderThread、GPU 和显示链路定位。一次采样栈不一定就是原始阻塞点,需要结合时间线。

修改要对应证据:主线程解析大段数据就移到后台,频繁全量刷新就合并更新,重复布局就减少无效层级或更新范围,锁内 IPC 就缩小锁范围。最后在相同机型、操作和数据条件下比较启动分位耗时、慢帧、ANR 与任务成功率,确保没有把性能问题变成错序或丢结果。

关键机制 ​

  • 先定义慢在哪里:页面可见、可交互、模型首输出、动作完成分别计时。
  • 线程栈解释“在做什么”,Perfetto 时间线解释“何时、等多久、被谁拖住”。
  • 看分布和回归,避免用一次最好成绩或不同测试条件得出结论。

通俗例子 ​

流式回答越长越卡:trace 显示主线程反复解析整段 Markdown 并触发大范围布局。可以后台增量处理、限制刷新频率、减少全量重绑,再观察长回答场景的帧耗时和内存是否改善。

追问与回答 ​

主线程栈里是 BinderProxy.transact,怎么继续? ​

这说明采样时主线程处于 Binder 调用相关路径,但还不能直接断定服务端哪一段慢。我会对齐调用时间与 Perfetto 的 Binder 事务,找到服务端处理线程,再看它是排队、等锁还是做耗时工作,同时检查是否存在嵌套调用或回调。优化时既处理服务端瓶颈,也避免 UI 主线程承担不可控的同步等待。

模型首字慢,应该怎样优化? ​

我会先拆开网络建连、服务排队、输入处理和首个输出的耗时,确认客户端能观察到哪些指标。上下文过长可以减少无关历史和检索片段,重复准备工作可以缓存,网络问题就处理连接复用或路径。界面先显示真实的执行状态改善感知,但不能把提前显示动画算作模型首字延迟降低。

易混淆点 ​

ANR 不是所有场景统一“5 秒”;onDraw 返回也不等于像素已经显示。CPU 占用低可能在等锁或 Binder,不等于没有性能问题。

参考资料 ​

内容来源 ​

用完整回答理解机制,用真实证据解释项目。