EN

Android 性能优化典范 - Render Performance

字数统计: 2.7k阅读时长: 9 min
2015/04/19
loading

系列文章目录:

  1. Android性能优化典范综述
  2. Android性能优化典范之Render Performance
  3. Android性能优化典范之Understanding Overdraw
  4. Android性能优化典范之Understanding VSYNC
  5. Android性能优化典范之Profile GPU Rendering

技术复核(2026-10-13):本文是 2015 年视频的学习笔记,Nexus 5 的例子和工具截图保留为历史材料。下方原视频简介中的 16ms 是 60Hz 的近似说法;正文已修正刷新、掉帧和调试工具的适用范围。

当时的视频简介:

Rendering performance is all about how fast you can draw your activity, and get it updated on the screen. Success here means your users feeling like your application is smooth and responsive, which means that you’ve got to get all your logic completed, and all your rendering done in 16ms or less, each and every frame. But that might be a bit more difficult than you think.

In this video, +Colt McAnlis takes a look at what “rendering performance” means to developers, alongside some of the most common pitfalls that are ran into; and let’s not forget the important stuff: the tools that help you track down, and fix these issues before they become large problems.

Android渲染知识

当你觉得自己开发了一个改变世界的应用的时候,你的用户可能并不会这么认为,他们认为你的应用又慢又卡,达不到他们所期望的那种顺滑,更谈不上改变这该死的世界了,回收站走你!等等!明明我这个应用在我的Nexus5上非常顺滑啊?你咋能说又慢又卡呢?如果你对Android的碎片化有一定了解的话,你就应该知道,很多低配置的手机并不像Nexus5那样有强大的处理器和GPU,以及没有被怎么污染的原生系统。

如果有大量的用户投诉说你的应用又卡又慢的时候,不要总是抱怨用户的低端手机,有时候问题就出在你的应用本身,可能涉及渲染、主线程阻塞等问题,需要先测量再定位。了解问题发生的根源,才能有效地解决问题。所以了解Android渲染相关的知识,是一个Android开发者必不可少的知识。

“16ms”对应的是 60Hz 下约 16.67ms 的显示间隔。90Hz、120Hz、144Hz 分别约为 11.11ms、8.33ms、6.94ms;应用的实际产帧期限还受调度和渲染流水线影响。不要只看某个函数是否超过 16ms,就认定整帧一定掉了或一定流畅。

设计与性能

渲染问题是开发应用时经常碰到的问题,一方面,设计师希望展现给用户一个超自然的体验,另一方面,这些华丽的动画和视图并不能在所有的Android手机上都流畅地运行。所以这就是问题所在。

Design vs Performance

绘制原理

Android 不会每隔 16ms 无条件重绘整个 Activity。在 View 体系中,内容失效、布局请求或动画等工作会推动下一帧;ViewRootImpl 把遍历回调交给 Choreographer 调度。静止且没有更新需求的界面,不需要仅因下一次刷新到来就重新执行整棵 View 树的绘制。这个按需调度在 Android 4.4.4 的 ViewRootImpl 和 Choreographer 中已经存在。

硬件加速也不意味着 CPU 不参与绘制。View 的测量、布局以及绘制命令记录需要 CPU;未失效的 display list 可以复用。Android 5.0 的 ThreadedRenderer 将渲染工作交给 RenderThread,GPU 异步执行命令,之后还要经过 SurfaceFlinger 的合成与显示。这几个阶段不能简化为“主线程结束,画面就已上屏”。硬件加速绘制模型

下面沿用原视频的 60Hz 简化图:连续动画的每一帧都赶上预期显示时机,视觉上才连贯。图里的 16ms 是约数,不是通用计时阈值。

Draw Good

如果某次更新花了 24ms,错过了原本要赶上的显示时机,就可能出现通常说的掉帧或卡顿(jank)。

Draw Bad

没有可用的新 buffer 时,SurfaceFlinger 可以继续使用此前的 buffer,屏幕不等于停止刷新;其他图层也可能继续更新。SurfaceFlinger 说明

在固定 60Hz、只错过一个显示时机的简化例子里,旧内容会持续约 33.33ms,而非通常的 16.67ms。原图的“34ms”和旧文的“32ms”都不应当作精确测量值。实际延迟还受缓冲、调度、GPU 完成及提交时机影响,不能仅凭“24ms”推算某台设备必定丢几帧。

掉帧

掉帧是用户体验中一个非常核心的问题,用户将很容易察觉到由于掉帧而产生的卡顿感,如果此时用户正在与系统进行交互,比如滑动列表,或者正在打字,那么卡顿感是非常明显的。用户会马上对你的应用进行吐槽,下一步工作肯定是回收站走你!所以弄清楚掉帧的原因是非常重要的。

不过蛋疼的是,引起掉帧发生的原因非常多,比如:

  • 频繁触发不必要的测量、布局或绘制命令记录,增加 CPU 工作
    Too Much View
  • 重复绘制最终被遮住的像素,增加渲染工作;具体代价还取决于裁剪、透明度和渲染器优化
    Draw Hidden View
  • 动画反复触发昂贵的布局或绘制;动画数量本身不能直接证明 CPU/GPU 已成为瓶颈
    Too Much Animations

检测和解决

检测和解决这些问题很大程度上依赖于你的应用程序架构,但是幸运的是,我们有很多开发者工具来协助我们发现和解决这些问题,有些工具甚至能追踪到具体出错的代码行数或者UI控件,这些工具包括但不限于:

Hierarchy View

Hierarchy View

旧 Hierarchy Viewer 用来观察 View 层级,查找不必要的嵌套;层级深只是一条排查线索,不等于已证明掉帧或过度绘制。图中界面和 Window → Open Perspective → Hierarchy View 属于当年的工具入口。它所在的 Android Device Monitor 已在 Android Studio 3.1 弃用、3.2 移除,这些操作说明已过期。

现在用 Layout Inspector 检查可调试应用的 View、Compose 或混合布局,查看层级、属性、快照及 Compose 重组/跳过信息。它帮助解释界面结构;是否耗时、是否错过期限,还要结合性能采集,不能只用节点数或重组次数判断。

On-Device Tools – Profile GPU Rendering 、Show GPU Overdraw、GPU View Updates

On-Device Tools

这些工具位于开发者选项,并非统一放在辅助功能里;名称和位置随系统版本、厂商而变。Android 4.2 起通常需要在“关于手机”中连续点击版本号七次来开启开发者选项。官方入口说明

  • Profile GPU/HWUI Rendering:用柱形图观察绘制阶段,适合快速找异常。名称虽有 GPU,统计的是 CPU 侧阶段和等待等耗时,不是 GPU 的纯执行时间;也不能覆盖所有自建 OpenGL/Vulkan 渲染路径。官方说明
  • Debug GPU Overdraw:查看受该工具覆盖的绘制中,同一像素是否被重复画过。它给出过度绘制线索,不直接给出整帧延迟或每个像素的执行成本,下一篇会继续讲。
  • Show GPU View Updates:旧版用闪烁标出更新区域。以 Android 4.4.4 HardwareRenderer 为例,debug.hwui.show_dirty_regions 在部分帧把 dirty rectangle 覆上半透明红色。没闪红不代表那块区域改由 CPU 软件绘制;它可能没有更新,或该帧没有显示覆盖层。不要把它当 CPU/GPU 区域分类器,也不要与 Show Surface Updates、Show Hardware Layer Updates 混为一谈。

TraceView

TraceView

Traceview 是旧的方法追踪查看器,图中主要是线程时间线和方法耗时统计,并非每一帧的显示时间线。它可以帮助找 Java 方法热点,不能完整描述 GPU 执行、跨进程调度和实际呈现时机,也不保证包含每个 native 函数。

Traceview 已弃用,Android Studio 3.2+ 使用 CPU Profiler 查看相关 .trace 文件。方法插桩会增加运行开销;采样对短方法也可能漏采,不能把一次追踪里的绝对耗时当未采集状态下的真实表现。方法追踪说明、追踪与采样的区别

今天排查这类问题,可以按三个步骤走:

  1. 用可复现的滑动或动画场景采集系统 trace。Android 12 / API 31+ 可看 Perfetto FrameTimeline 的预期与实际时间线,核对 jank 原因、应用帧与 SurfaceFlinger 的关联;旧系统和未被覆盖的渲染路径不能凭空得到同样的轨道。
  2. 对异常帧检查已采集到的主线程、RenderThread、调度与 GPU 证据。CPU 算得慢、等待锁、没被调度以及 GPU 尚未完成,是不同的问题;系统 trace 也不会自动记录每个函数。
  3. 修复后以相同设备和场景做 Macrobenchmark 回归。FrameTimingMetric 从 AndroidX Benchmark 1.1.0 提供,frameOverrunMs 要求 API 31+;按配置要求使用 non-debuggable、profileable 的目标应用,别把 Layout Inspector 调试会话当性能基准。

Perf Matters

keep calm, profile your code, and always remember, Perf Matters

总结

这是这个系列视频的第一个视频,从内容上来看,是从一个大的角度来看Render Performance,简单地讲述了一下Render Performance基本的概念,出现的原因以及排查的工具。在发现问题–定位问题–解决问题的流程上属于发现问题–定位问题,解决问题则基本没有提到。这也基本符合这一系列视频的基调:即着重于发现问题(使用工具发现问题、挖掘问题出现的原理和原因)和定位问题(使用工具定位),如何解决问题则需要自己通过实战去进行锻炼,毕竟这种问题并没有一个通用的解决方法,每个应用都有每个应用自己的问题。

关于我 && 博客

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

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

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

微信扫一扫

CATALOG
  1. 1. Android渲染知识
  2. 2. 设计与性能
  3. 3. 绘制原理
  4. 4. 掉帧
  5. 5. 检测和解决
    1. 5.1. Hierarchy View
    2. 5.2. On-Device Tools – Profile GPU Rendering 、Show GPU Overdraw、GPU View Updates
    3. 5.3. TraceView
  6. 6. Perf Matters
  7. 7. 总结
  • 关于我 && 博客