内容提要
本文聚焦交互首帧响应,使用 Perfetto 度量从 InputReader 读取事件到首帧 present 的延迟,主指标为 input_to_present_ms。文章将响应慢拆分为 read/dispatch、handling、ACK 到首帧、滑动跟手四项,给出采集配置、SQL 查询与 App marker 方法,并归纳常见归因路径及高速相机与 Perfetto 的边界。
延伸解读
input_to_present_ms 的边界:它测什么,不测什么
文章明确 input_to_present_ms 只覆盖从 InputReader read_time 到关联帧 present 的系统内部时间,不包含触控 IC、驱动上报前延迟、显示扫描和面板响应。标准库给出的 present 是候选关联,is_speculative_frame=false 仅表示输入处理切片与同线程 doFrame 相交,不能证明业务因果或目标 layer 已发生视觉变化。因此查询统一输出 estimated_input_to_present_ms,只有另行核对目标 layer、frame t
四个指标拆分:避免把响应慢混为一谈
文章把响应慢拆成 read/dispatch、handling、ACK 到首帧、滑动跟手四个独立指标。Dispatch latency 衡量 InputDispatcher 发出事件到 App 收到事件;Handling latency 衡量 App 收到事件到发出 ACK;input_to_present_ms 衡量 input read 到关联帧 present;Completion latency 衡量业务触发点到页面或动画稳定。用户最敏感的是 input_to_present_ms,第一次反馈快,后续内容分
采集配置与数据质量:先确认信号可用性
文章给出 lab_input_debug 和 field_input_response_low_overhead 两层 preset。android.input.inputevent 面向 debuggable system build,TRACE_MODE_TRACE_ALL 只适合本地设备和测试,field/user build 上不要依赖。android_input_events 从 ATrace 的 sendMessage/receiveMessage、deliverInputEvent 等切片重建往返和帧
常见归因路径:从指标异常到排查方向
文章归纳五条常见归因路径。read_to_dispatch_ms 或 dispatch_latency_dur 高,优先检查 InputReader 到 InputDispatcher 之间是否排队、system_server 是否 Runnable 等待、窗口焦点和 InputChannel 状态。handling_latency_dur 高,优先检查 App 主线程收到 input 后是否长时间 Running、click handler 是否同步发 Binder 或等锁。ACK 快但 first frame
Q&A
Perfetto 中 input_to_present_ms 指标具体度量的是哪段时间?
input_to_present_ms 度量从 InputReader 读到输入事件(read_time)到关联帧 present 的延迟,SQL 字段对应 end_to_end_latency_dur。它回答“点了以后多久有第一帧反馈”,不覆盖触控 IC、驱动上报前延迟、显示扫描和面板响应。
分析交互响应慢时,应该把响应过程拆成哪四个指标?
拆成四个独立指标:Dispatch latency(InputDispatcher 发出事件到 App 收到事件)、Handling latency(App 收到事件到发出 ACK)、input_to_present_ms(input read 到关联帧 present)、Completion latency(业务触发点到页面或动画稳定)。
采集输入响应 Trace 时,android.input.inputevent 数据源有什么使用限制?
android.input.inputevent 面向 debuggable system build(userdebug/eng 等受控环境),TRACE_MODE_TRACE_ALL 会记录系统处理的输入事件,只适合本地设备和测试。field/user build 上不要依赖它;如需降低隐私风险,只能用 TRACE_MODE_USE_RULES 并配合严格匹配规则、secure/IME/spy window 审查和访问控制。
在 Perfetto UI 中分析一次点击响应,应该按什么顺序查看轨道?
建议顺序:InputReader/InputDispatcher 确认事件是否读到并派发;App 主线程确认事件到达后是否马上 Running;Choreographer#doFrame 确认状态变化通过哪种回调推进;RenderThread 确认是否卡在 syncFrameState、DrawFrame 等阶段;FrameTimeline 确认关联帧的 expected/actual 和 layer_name;SurfaceFlinger 确认 buffer 是否及时 latch;CPU scheduling/frequency 确认是否有 Runnable 等待或频率不足。
滑动场景中,如何定义“跟手”的起点和终点?
推荐口径:起点为第一个业务有效 ACTION_MOVE(排除 touch slop 内的小幅 MOVE),终点为内容第一次可见位移的 present。需要记录 first_effective_move_ts、first_offset_change_ts、offset_delta_px、touch_slop_px 和 sample_policy,并用 App counter 或外部视频确认内容确实发生位移。
ACK 很快但首帧仍然慢,通常需要排查哪些方向?
优先检查:App 是否没有请求下一帧或请求太晚;ACK 后是否在等 Binder 回调、Activity/Fragment transaction、数据回调或窗口切换;Animation/Traversal 是否排到后一个 Vsync;RenderThread 是否卡在 syncFrameState、DrawFrame;dequeueBuffer/queueBuffer 是否说明 BufferQueue backpressure;GPU 完成、acquire/release fence、present fence 是否拖住;SurfaceFlinger/HWC/GPU composition 是否让 display frame 晚于预期;主线程或 RenderThread 是否 Runnable 等待 CPU。
高速相机和 Perfetto 在响应速度分析中各自的作用和边界是什么?
高速相机/机械手得到用户可见延迟,定义外部起点和终点;Perfetto 拆内部耗时,定位 Input、App、RenderThread、SurfaceFlinger、CPU/GPU 哪一段慢;App marker 标记业务点击、转场开始、首屏内容完成、scroll offset 变化。外部测量给结果,Perfetto 给原因,App marker 给业务语义。没有外部测量时,报告只能写系统内部延迟,不能写用户可见绝对延迟。
input_to_present_ms 为 NULL 是否代表没有视觉反馈?
不一定。end_to_end_latency_dur 为 NULL 可能是事件没有关联到 FrameTimeline 帧,也可能是反馈发生在 SurfaceView、游戏引擎或另一个 layer 上。遇到这种情况要回到 App marker、SurfaceFlinger、外部视频或领域工具,不要把 NULL 写成“没有绘制”。