EN

Android Systrace 响应速度实战 1 :了解响应速度原理

字数统计: 5.3k阅读时长: 18 min
2021/09/13
loading

在讨论 Android 性能问题的时候,卡顿、响应速度、ANR 常会一起出现,部分原因也会重叠,但它们不是按严重程度划分的同一个问题。画面节奏异常、操作反馈延迟和具体超时机制触发的 ANR,需要分别确认。用户说“手机卡”或“App 卡”时,可以先把它当作宽泛的体验描述,再问清发生了什么、从哪个动作到哪个结果变慢。

动画播放或列表滑动不连贯,通常称为 Jank;应用启动、亮灭屏或场景切换耗时较长,可描述为 响应慢(slow response / high latency);ANR 则是 Application Not Responding。这些说法帮助组织问题,不是互斥分类;高延迟也可能同时伴随卡顿,ANR 还要按具体触发类型分析。

另外在 App 或者厂商内部,卡顿、响应速度、ANR 这几个性能指标都是有单独的标准的,比如 掉帧率、启动速度、ANR 率等,所以针对这些性能问题的分析和优化能力,对开发者来说就非常重要了

本文是响应速度系列的第一篇,主要讲响应速度相关的理论知识,包括性能工程概述、响应速度涉及到的知识点,以及分析方法。

版本说明(2026-10-14 核查):本文发表于 2021 年,保留方法论、书摘和原图;修正了“线程状态直接决定应用/系统责任”和“Message 执行完就是响应完成”的简化。启动初始化以 AOSP android-11.0.0_r1 为源码参考,补充 TTID/TTFD、Android 12(API 31)SplashScreen 和现代分析工具的边界。

本文目录

关于卡顿的文章可以参考这一篇 Systrace 流畅性实战 1 :了解卡顿原理 ,ANR 的文章后续会介绍,本文主要是讲响应速度相关的基本原理

Systrace (Perfetto) 工具的基本使用如果还不是很熟悉,那么需要优先去补一下 Systrace 基础知识系列,本文假设你已经熟悉 Systrace(Perfetto)的使用了

性能工程

在介绍响应速度的原理之前,这里先放一段 《性能之巅》 这本书中对于性能的描述,具体来说就是方法论,非常贴合本文的主题,也强烈推荐各位搞性能优化的同学,把这本书作为手头常读的方法论书籍:

性能是充满挑战的

系统性能工程是一个充满挑战的领域,具体原因有很多,其中包括以下事实,系统性能是主观的、复杂的,而且常常是多问题并存的

性能是主观的

  1. 技术学科往往是客观的,太多的业界人士审视问题非黑即白。在进行软件故障查找的时候,判断 bug 是否存在或 bug 是否修复就是这样。bug 的出现总是伴随着错误信息,错误信息通常容易解读,进而你就明白错误为什么会出现了
  2. 与此不同,性能常常是主观性的。开始着手性能问题的时候,对问题是否存在的判断都有可能是模糊的,在问题被修复的时候也同样,被一个用户认为是“不好”的性能,另一个用户可能认为是“好”的

系统是复杂的

  1. 除了主观性之外,性能工程作为一门充满了挑战的学科,除了因为系统的复杂性,还因为对于性能,我们常常缺少一个明确的分析起点。有时我们只是从猜测开始,比如,责怪网络,而性能分析必须对这是不是一个正确的方向做出判断
  2. 性能问题可能出在子系统之间复杂的互联上,即便这些子系统隔离时表现得都很好。也可能由于连锁故障(cascading failure)出现性能问题,这指的是一个出现故障的组件会导致其他组件产生性能问题。要理解这些产生的问题,你必须理清组件之间的关系,还要了解它们是怎样协作的
  3. 瓶颈往往是复杂的,还会以意想不到的方式互相联系。修复了一个问题可能只是把瓶颈推向了系统里的其他地方,导致系统的整体性能并没有得到期望的提升。
  4. 除了系统的复杂性之外,生产环境负载的复杂特性也可能会导致性能问题。在实验室环境很难重现这类情况,或者只能间歇式地重现
  5. 解决复杂的性能问题常常需要全局性的方法。整个系统——包括自身内部和外部的交互——都可能需要被调查研究。这项工作要求有非常广泛的技能,一般不太可能集中在一人身上,这促使性能工程成为一门多变的并且充满智力挑战的工作

可能有多个问题并存

  1. 找到一个性能问题点往往并不是问题本身,在复杂的软件中通常会有多个问题
  2. 性能分析的又一个难点:真正的任务不是寻找问题,而是辨别问题或者说是辨别哪些问题是最重要的
  3. 要做到这一点,性能分析必须量化(quantify)问题的重要程度。某些性能问题可能并不适用于你的工作负载或者只在非常小的程度上适用。理想情况下,你不仅要量化问题,还要估计每个问题修复后能带来的增速。当管理层审查工程或运维资源的开销缘由时,这类信息尤其有用。
  4. 有一个指标非常适合用来量化性能,那就是 延时(latency)

– 以上几段内容摘录自 《性能之巅》

上面的书摘用于说明体验差异和系统复杂性,不表示响应时间无法客观测量。实际 bug 也可能没有错误日志;性能问题一旦约定起止点、负载和测量方式,就可以重复比较。书籍信息可见 作者页面。

Systrace 系列文章如下

  1. Systrace 简介
  2. Systrace 基础知识 - Systrace 预备知识
  3. Systrace 基础知识 - Why 60 fps ?
  4. Systrace 基础知识 - SystemServer 解读
  5. Systrace 基础知识 - SurfaceFlinger 解读
  6. Systrace 基础知识 - Input 解读
  7. Systrace 基础知识 - Vsync 解读
  8. Systrace 基础知识 - Vsync-App :基于 Choreographer 的渲染机制详解
  9. Systrace 基础知识 - MainThread 和 RenderThread 解读
  10. Systrace 基础知识 - Binder 和锁竞争解读
  11. Systrace 基础知识 - Triple Buffer 解读
  12. Systrace 基础知识 - CPU Info 解读
  13. Systrace 流畅性实战 1 :了解卡顿原理
  14. Systrace 流畅性实战 2 :案例分析: MIUI 桌面滑动卡顿分析
  15. Systrace 流畅性实战 3 :卡顿分析过程中的一些疑问
  16. Systrace 响应速度实战 1 :了解响应速度原理
  17. Systrace 响应速度实战 2 :响应速度实战分析-以启动速度为例
  18. Systrace 响应速度实战 3 :响应速度延伸知识

响应速度概述

响应速度是应用 App 性能的重要指标之一。响应慢通常表现为点击效果延迟、操作等待或白屏时间长等,主要场景包括:

  • 应用启动场景,包括冷启动、热启动、温启动等
  • 界面跳转场景,包括应用内页面跳转、App 之间跳转
  • 其他非跳转的点击场景(开关、弹窗、长按、控件选择、单击、双击等)
  • 亮灭屏、开关机、解锁、人脸识别、拍照、视频加载等场景

响应时间应定义为:从约定触发事件到约定结果的时间差。触发可以是触摸、通知/Intent、系统动作或应用内部事件。触摸输入经 InputChannel/native Looper 进入处理链,不是每个硬件事件都直接变成一条 Java Message;长按通常由手势逻辑判定,指纹识别等也有独立的硬件/服务回调路径。

终点可能是按钮首次视觉反馈、页面第一帧、重要内容可用、拍照结果生成或屏幕实际点亮,必须分别命名。主线程 Message 完成之后,仍可能有工作线程、网络、GPU、合成与显示等待。下面的主线程图只展示应用事件与绘制交替,不能表示所有响应场景的完整链路。

XyGmCIpqfZxRFCs7

用户期待带有主观性,但约定范围内的时延可以客观测量。流畅度也需要说明目标节奏、场景和呈现判定,不能简单对立为“响应主观、掉帧绝对客观”。不同角色可以选择不同观察点,但必须保留名称和边界:

观察范围 常见起止点 容易遗漏的部分
系统/端到端分析 约定输入事件、系统启动请求 → 对应结果或呈现 硬件接触、中断、InputReader 时间戳并非同一点;日志可能未覆盖物理显示
应用阶段分析 attachBaseContext / Application.onCreate → 应用定义的就绪状态 不含之前的调度、进程创建等;从 onCreate 开始还可能漏掉 Provider 初始化
体验测试 自动化/机械触发 → 约定视觉变化或可用状态 图标变色已经是一次反馈,若以它作起点会漏掉此前延迟;相机/识别有采样误差

这些不是各角色必须遵守的唯一方法。可以用高速相机、自动化或应用埋点交叉核验,也可以由系统与应用协作;不应把某一种测试设备组合称为所有团队的标准。

启动指标补充:Android 官方区分 TTID 与 TTFD。TTID 衡量框架定义的启动到首帧显示,Displayed 日志可用于观察它;TTFD 通过应用报告关键内容已就绪来补充。二者都不等于物理触摸到屏幕发光的端到端计时。

Activity.reportFullyDrawn() 自 API 19 提供,需要在重要数据和 UI 满足约定的可用条件时调用;调用过早/过晚都会改变指标含义,未报告则是缺数据。Android 12(API 31)起的 SplashScreen 又增加了系统启动画面及退出过程,必须区分启动画面、应用首帧、关键内容和可交互状态。展示更快的占位画面可以改善反馈,但不等于实际工作已经完成。

响应速度问题分析思路

分清起点和终点

分析前先统一起点、终点、时间源和判定规则,并记录冷/温/热启动状态、编译/预热状态、登录/数据量、网络、显示模式、温度及后台负载。相同起止点下再比较分布与长尾,不能将不同起点得到的数字并排排名。

  1. 竞品分析。一般来说,响应速度这个指标都会有一个对标的竞品,竞品手机或者竞品 App,相同的条件下,竞品手机或者竞品 App 从点击到响应花费了多少时间,可以作为一个标准
  2. 对比前一个版本。有时候系统进行大版本升级或者 App 进行版本迭代,那么上一个版本的数据就可以拿来作为标准进行对比

拿淘宝这样的复杂页面来说,究竟到哪一步才算启动完成?这个终点就不太好定。起点也可能有歧义:手指接触、ACTION_DOWN、ACTION_UP、点击回调和启动请求相差一段时间。终点则要由场景决定。Displayed 对 TTID 有明确用途,不能笼统说“不准确”;它不代表全部内容加载完成。onWindowFocusChanged() 是焦点变化通知,不是完成协议。若测量用户所需内容,应定义可验证的就绪条件,再用埋点、自动化或高速摄影核对。

响应速度常见问题

Android 系统自身原因导致响应慢

下面是可能涉及系统资源或跨进程依赖的情况。线程状态是排查线索,不是责任划分;同一种表现可能来自应用、服务端或资源争用。

线索 可能原因 需要补的证据
Running 较长 更多指令/绘制工作、频率/核心能力、缓存或内存访问、驱动执行 同负载调用栈、实际核心拓扑/驻留、频率及限制、硬件计数(若可用)
Runnable 较长 等 CPU、优先级/亲和性/cpuset 限制、其他任务竞争 sched_switch/wakeup、可运行 CPU 集合、优先级和每核忙闲;不一定整机满载
同步 Binder 调用等待 远端排队、执行、锁或嵌套调用 对应 transaction 与服务端线程;服务端不一定是 system_server
Sleep/锁等待 条件变量、子线程/其他进程、网络回调或锁 等待栈、锁持有者及唤醒路径;waker 不必就是根因或锁持有者
D/Uninterruptible Sleep 某些内核等待,包括 I/O,也可能是其他不可中断等待 blocked reason、内核栈、块设备/文件 I/O;不能直接等同低内存
频率上限下降 温控、功耗或其他策略限制 温控状态、频率 policy/限制与同场景对照;低频本身不是错误
Buffer 操作较长 空闲槽位不足、消费滞后、fence、驱动或 Binder 等待 具体生产/消费路径、buffer/fence 与调用链;不只看 SurfaceFlinger

低内存 可能通过回收、缺页、压缩/交换、进程被杀后重建及 I/O 影响延迟,但要用内存与压力、回收、fault、lmkd 等事件关联。ART 的 HeapTaskDaemon 管理托管堆任务,kswapd 管理内核页回收,二者不是同一个 GC;任务频繁也不能单独证明系统低内存。支持的 Linux/Android 环境可结合 PSI,没有采集不代表压力为零。

SystemServer 处理启动请求较慢时,目标应用甚至可能尚未创建,不能一律描述成“应用主线程 Sleep 等 Binder”。SurfaceFlinger 相关图形路径也随版本变化:例如 AOSP android-16.0.0_r1 的 BLASTBufferQueue 在客户端管理队列并提交事务,不能假定所有 dequeue/queue 都在 SF 的 Binder 线程中处理。

应用自身原因

应用可先检查必要初始化和依赖,判断哪些工作确实位于当前响应的关键路径上:

  1. Application.attachBaseContext()、onCreate()、类加载/静态初始化和 SDK 初始化;只测 onCreate 会漏掉之前的工作。
  2. Activity 的 onCreate → onStart → onResume 等回调及恢复路径;回调返回不表示画面已呈现。Service、BroadcastReceiver 的默认主线程回调也可能与 UI 竞争,但不能把每个长回调都叫系统 timeout。
  3. ContentProvider 初始化。在 AOSP android-11.0.0_r1 的 ActivityThread 正常绑定路径中,安装 Provider 位于 Application.onCreate() 前。初始化通常在主线程,远程数据访问则需按 Binder 等实际调用线程分析。
  4. View inflate、measure/layout/draw,或 Compose 的首次组合/布局;并非每次响应都执行所有阶段。图形栈初始化、纹理上传、Surface/fence 等待与每帧 queue/dequeue 也应分开。
  5. 启动中额外的 SplashActivity → MainActivity 跳转、重复加载和异步数据依赖。Android 12+ 需结合系统 SplashScreen 设计,不应仅为启动动画多加一层 Activity。
  6. 主线程长 Message,以及等待工作线程、其他进程、网络或同步 Binder 返回。等待与本地计算要分开,异步化也不自动缩短用户需要的最终结果时间。
  7. WebView 创建、资源读取、类加载、JIT/AOT 与编译配置。不能把所有首次运行耗时都归为 JIT;测试需记录安装、编译和预热状态。

AndroidX App Startup 可集中管理初始化依赖,也支持关闭自动初始化后按需初始化;引入库不会自动消除实际工作量。推迟非首屏必要工作前,应检查线程要求、依赖及首次使用时的延迟,避免只是把卡顿移到下一次操作。

响应速度问题分析套路(以 Systrace 为主)

  1. 固定场景与测量口径:记录设备/系统/应用版本、数据与账号、启动状态、缓存/编译状态、网络和温控。明确触发、终点、时钟和成功条件,失败/未完成的样本单独统计,不当成零耗时。
  2. 捕获覆盖关键路径的证据:使用 Perfetto/Systrace、相关 log 和应用 trace 标记。确认采集范围、缺失事件与丢失数据;主线程方法图不足以覆盖整机。跨进程标记需要可关联的 ID,时间源不同需先对齐。
  3. 按依赖拆阶段:可从启动请求、进程创建、Provider/Application、Activity、首帧,到后续关键内容/可用状态拆分。并行阶段不能直接相加;优化位于关键路径上的工作后,瓶颈也可能转移。
  4. 按状态提出假设,再查证:Running 长就查执行栈和资源,Runnable 长就查可运行资源与竞争,Sleep 就查依赖,D 状态就查具体内核等待。不要从一个状态直接宣布“应用问题”或“系统问题”。I/O 与内存的关系可参考 主线程 I/O。
  5. 沿对应区域继续追踪:
    • Kernel:确认实际核心 topology/capacity,不把 CPU 0–3 当所有机器的小核;频率未到最大值不自动有错,一个线程跑满也不等于多核整机满载。结合 容量调度说明 和实际 policy/允许 CPU 集合判断。
    • SystemServer:关联输入、启动请求、Binder 和锁链;应用未创建时从服务端继续查。锁等待需确认持有者,不能把所有 Binder 线程的 Sleep 都当 AM/WM 锁。
    • SurfaceFlinger:先认清当前图形路径,再关联提交、fence、合成与呈现。queue/dequeue 长也可能源于客户端或驱动。
    • Launcher:仅当启动来自桌面时分析其点击、暂停和转场;通知/深链启动不必经过 Launcher。动画与内容准备可能重叠,不把整段动画时长直接加进启动耗时。
  6. 需要函数细节时补充工具:Traceview 已弃用,Android Studio CPU Profiler 是其替代入口,不是同一个工具的新名字。simpleperf 的能力取决于系统、符号和调试/profileable 权限;Android 10 起可按官方方案配置 profileable 发布构建。原文 TraceFix 是插桩工具示例,使用前核对当前构建链兼容性。采样与插桩覆盖不同,额外开销应单独评估。
  7. 按相同口径复测并协作处理:优先处理对关键路径影响最大的项,重复测量并报告样本数、分位数和未完成比例。厂商/应用协作接口需确认具体版本和合同,不假设私有 SDK 普遍可用;有些限制暂时无法解决,或者影响很小,也要把证据和影响范围跟测试同学说清楚。历史 Bug 可提供线索,仍需检查当前版本是否同因。

本篇文章主要是一个响应速度基础知识方面的一个普及,其中涉及到大量的系统知识,不熟悉的同学可以跟着 Systrace 基础知识系列 过一下

系列文章

  1. Systrace 响应速度实战 1 :了解响应速度原理
  2. Systrace 响应速度实战 2 :响应速度实战分析-以启动速度为例
  3. Systrace 响应速度实战 3 :响应速度延伸知识
  4. Systrace 基础知识系列-放个链接在这里方便大家直接点过去

参考文章

  1. Android 应用启动全流程分析
  2. 探究 | App Startup 真的能减少启动耗时吗
  3. Jetpack 新成员,App Startup 一篇就懂
  4. App Startup
  5. Android App 启动优化全记录
  6. Android application profiling

关于我 && 博客

下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!

  1. 博主个人介绍 :里面有个人的微信和微信群链接。
  2. 本博客内容导航 :个人博客内容的一个导航。
  3. 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
  4. Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。

一个人可以走的更快 , 一群人可以走的更远

微信扫一扫

CATALOG
  1. 1. 本文目录
  • 性能工程
  • 性能是充满挑战的
    1. 1. 性能是主观的
    2. 2. 系统是复杂的
    3. 3. 可能有多个问题并存
  • 响应速度概述
  • 响应速度问题分析思路
    1. 1. 分清起点和终点
    2. 2. 响应速度常见问题
      1. 2.1. Android 系统自身原因导致响应慢
      2. 2.2. 应用自身原因
    3. 3. 响应速度问题分析套路(以 Systrace 为主)
  • 系列文章
  • 参考文章
  • 关于我 && 博客