瀑布图基础 —— 从一片彩色条块中读出构建故事

我第一次打开 AGP 构建分析的瀑布图时,说实话有点懵。

满屏花花绿绿的色块,横轴是时间,纵轴是一堆不认识的任务名。你想想看,一个中型项目光 task 就有上百个,全堆在一张图里,怎么看?

后来我花了两个下午,硬是把每个色块的含义、每个阶段的划分逻辑摸了一遍。从那以后,每次 AGP 版本升级、每次构建变慢,我第一件事就是拉瀑布图。说白了,它就像构建过程的“心电图”,哪儿堵了、哪儿慢了,一眼就能看个大概。

这一章我就把自己读瀑布图的经验拆开来讲。你会发现,这东西没那么玄乎。

瀑布图到底长什么样?

先给个直观印象。下图是我简化后的瀑布图结构,展示了一次构建中几个核心阶段的时间消耗情况。

瀑布图结构解析 —— 一次构建的“时间切片” 0s 2s 4s 6s 8s 配置阶段 编译阶段 处理资源 打包阶段 签名阶段 80ms 3.8s ⚠️ 瓶颈 2.1s 2.6s 0.5s ⏱ 时间轴(横轴) 从左到右 = 时间流向 色块宽度 = 任务耗时 📋 阶段划分(纵轴) 每个阶段一个色块行 阶段间通常有依赖顺序 🎨 色块 = 任务 颜色 = 任务类型/归属 位置 = 执行顺序 🔍 瓶颈诊断 最宽的色块 = 瓶颈 红色标注 ⚠️ 优先优化 ⚡ 并串行关系 上下对齐 = 并行执行 首尾相接 = 串行依赖
💡 快速记忆法: 横轴看时间,纵轴看工序,色块看任务,宽窄看耗损。把这四句话记住,瀑布图你就读懂了一半。

时间轴 —— 构建的“时钟”

横轴就是时间轴。它的起点是构建开始,终点是构建结束。中间每一个色块从左到右延伸的距离,就是那个任务花掉的时间。

我个人习惯先看总时长。比如上图中,从 0s 到 8s 左右,总耗时约 8 秒。然后我会快速扫一眼哪个色块最长。你看编译阶段那个红色块,占了快一半的时间,这肯定有问题。

时间轴的单位通常是毫秒或秒。AGP 生成的瀑布图会自适应缩放,你鼠标悬停在色块上能看到精确数值。

阶段划分 —— 构建的“工序”

纵轴按阶段把任务分组。每个阶段里可能包含多个子任务,但瀑布图默认会按阶段聚合展示。

常见的阶段包括:

阶段名称 包含任务 典型耗时占比
配置阶段 读取 build.gradle、解析依赖、初始化插件 1-5%
编译阶段 Java/Kotlin 编译、APT、注解处理 40-60% ⚠️ 通常为瓶颈
资源处理 AAPT2、资源合并、shrink 15-25%
打包阶段 DEX 编译、APK 打包、混淆 15-30%
签名阶段 APK 签名、zipalign 1-3%

我以前在优化一个项目时,发现资源处理阶段特别长。当时以为是图片太多导致的,后来点开瀑布图细看,才发现是 AAPT2 在合并某个大模块的 assets 时卡住了。嗯,这就是阶段划分的价值 —— 帮你快速锁定“哪个工序”出了问题。

色块含义 —— 每一种颜色都在说话

色块是瀑布图的最小信息单元。每一个色块代表一个具体的 Gradle Task。颜色本身没有固定的全局含义,但在同一张图中,同一种颜色通常代表同一类任务或同一个模块。

举个例子:在 AGP 生成的瀑布图里,蓝色可能是配置类任务,红色是编译类任务,绿色是资源类任务。但不同版本的 AGP 配色方案可能不一样,所以别死记颜色,要看图例。

读色块时我一般关注三个信息:

  • 宽度 —— 耗时。越宽越可疑。
  • 位置 —— 执行顺序。靠左的先执行,靠右的后执行。
  • 上下关系 —— 如果两个色块在纵轴上重叠(同一时间段内都有任务),说明它们在并行执行。如果一前一后紧挨着,说明有串行依赖。
🔎 我的读图顺序:
1. 先看总时长 —— 心里有个底
2. 找最宽的色块 —— 大概率是瓶颈
3. 看瓶颈色块所属的阶段 —— 锁定了,就是它
4. 观察瓶颈前后是否有串行等待 —— 有时候不是任务本身慢,是它在等别的任务完成
5. 对比两次构建 —— 比如升级 AGP 前后的瀑布图并排看,差距一目了然

如何快速定位瓶颈?三个实用技巧

上面讲的都是基础,下面说点实战的。我在诊断构建速度时,会用到三个技巧:

  1. 找“最宽的红色块” —— 编译阶段通常占大头,但如果某个模块的编译色块明显比别的宽,那就是它拖了后腿。
  2. 找“串行长链” —— 如果瀑布图上出现一长串首尾相接的色块,中间没有任何并行,那这条链就是构建的“单行线”。我曾经遇到过一个项目,因为模块依赖没配好,导致 6 个模块串行编译,白白多花了 3 秒。
  3. 找“空白间隙” —— 色块之间的空白区说明 CPU 在等待 I/O 或等待其他任务完成。空白太多,说明并行度没跑满。
⚠️ 避坑指南: 我曾经在分析一个项目的瀑布图时,发现某个色块特别宽,第一反应是“这个模块代码太多了”。花了一天时间拆模块、做增量编译优化,结果没什么效果。后来仔细看才发现,那个色块之所以宽,是因为它依赖了一个远程 Maven 仓库的下载任务 —— 网络慢,不是编译慢。所以,读瀑布图时别只看色块本身,也要看它“背后”依赖了哪些任务。

小结

瀑布图说白了就是一张“构建时间地图”。横轴是时间,纵轴是工序,色块是任务。你只要学会看宽窄(耗时)、看颜色(类型)、看位置(顺序),就能快速找到构建的瓶颈点。

下一层楼,我们会拿一份真实的 AGP 升级前后瀑布图做对比分析,看看升级到底带来了哪些变化。但我先把话说在前面——升级不一定全是好事,有时候旧版本里的“隐形优化”在新版本里被拿掉了,瀑布图会诚实地告诉你一切。