4. Gradle Build Scan 简介
说到构建速度优化,很多人一上来就去翻 build.gradle,改配置、调参数,忙活半天发现没啥效果。嗯,我刚开始也这么干过。后来踩了一次坑,花了两天时间排查一个第三方插件导致的构建变慢,最后发现其实用 Build Scan 看一眼就能定位。
Build Scan 是什么?说白了就是 Gradle 提供的构建过程快照。它能把你整个构建过程的每一步——任务耗时、依赖解析、缓存命中、配置阶段开销——统统记录下来,生成一个可交互的网页报告。我个人习惯把它叫做「构建者的 X 光机」。
核心思想:不要猜,直接看数据。Build Scan 帮你把构建过程可视化,瓶颈在哪一清二楚。
把 Build Scan 跑起来
使用 Build Scan 非常简单。AGP 从 4.2 开始就原生支持了,到了 AGP 7.0 以后基本开箱即用。
你只需要在构建命令后面加个 --scan 参数:
./gradlew assembleDebug --scan
构建完成后,控制台会输出一个链接。点开它,你就进入了 Build Scan 的世界。
我个人习惯在 CI 上也加上 --scan。每次构建完自动生成一个链接,粘贴到任务评论里。排查问题的时候简直不要太方便。
如果你用的是 AGP 7.0+,连 Gradle Enterprise 都不需要额外配置。第一次运行时会提示你同意条款,同意一次以后就不再问了。
Build Scan 能告诉你什么?
我挑几个最有用的页面说。
| 页面 / 标签 | 核心作用 | 我重点关注 |
|---|---|---|
| Performance | 总耗时、配置阶段耗时、任务耗时、GC 时间 | 配置阶段 > 5s 就要警惕 |
| Timeline | 瀑布图展示每个任务的起止时间、并行情况 | 看有没有长串串行任务阻塞 |
| Dependencies | 依赖解析过程、版本冲突、依赖树 | 检查是否解析了过多 SNAPSHOT |
| Cache | 构建缓存命中/未命中详情 | 看哪些任务总是 miss,原因是什么 |
| Test | 测试执行时间分布 | 找慢的单测,考虑并行或拆模块 |
用瀑布图抓「慢任务」
Timeline 页面是网络瀑布图的核心。它会按时间轴展示所有任务的执行过程。
你想想看,如果一个 Task 耗时 30 秒,而其他 Task 早就跑完了,那这个 Task 就是瓶颈。点进去还能看到它的输入、输出、缓存 key 等信息。
我曾经遇到过一个问题:每次构建 release 版本都要多花 40 秒。打开 Timeline 发现 transformClassesAndResourcesWithProguardForRelease 任务独占 CPU 跑了一分钟,其他任务全在等它。后来通过给 ProGuard 分配更多堆内存解决了。
注意:Timeline 里每个任务的颜色代表任务类型(绿色=成功,红色=失败,灰色=up-to-date,蓝色=FROM-CACHE)。别把灰色的 up-to-date 任务当成耗时任务。
Dependencies 页面:揪出依赖耗时
依赖解析是很多人容易忽略的瓶颈。尤其是在使用了大量动态版本(2.+)或者 SNAPSHOT 版本时,Gradle 要每次都去远程仓库检查更新,拖慢构建。
Build Scan 的 Dependencies 页面会展示每个依赖的解析耗时、来源仓库、版本冲突。我个人常用的套路是:
- 找到解析耗时最长的几个依赖
- 检查它们是否都是 SNAPSHOT 或动态版本
- 如果可能,改为固定版本号
- 如果必须用 SNAPSHOT,考虑配置
changing=true加较长的缓存过期时间
举个例子,有一次我团队的构建每次都要花 8 秒解析某个 SNAPSHOT 依赖。改了固定版本后,直接降到 0.2 秒。
Cache 页面:看你的缓存有没有生效
Build Scan 的 Cache 页面会把所有任务按缓存结果分类:
- FROM-CACHE:从本地缓存取到了
- REMOTE-CACHE:从远程缓存下载了
- UP-TO-DATE:没变,直接跳过
- EXECUTED:重新执行了
如果某个任务反复出现 EXECUTED,说明它的输入(如文件路径、依赖版本、甚至环境变量)一直在变。点进去看「Inputs」就知道原因了。
我记得有一次,某个模块的 compileDebugJavaWithJavac 每次都执行,查了 Inputs 发现是因为构建脚本里动态生成了一个版本号文件,导致每次输入都不同。后来把版本号文件排除在增量检查之外就解决了。
避坑指南
我曾经遇到过一个问题:Build Scan 生成后链接在 7 天后就失效了,需要登录 Gradle 才能查看。如果你需要长期保留报告,建议配置 Gradle Enterprise 或使用 --no-scan 后自行上传。
另外,Build Scan 默认只保留最新 5 次扫描记录。如果你是在 CI 上批量生成,记得通过 Gradle Enterprise 的 API 把关键构建的扫描结果保存下来。
一句话总结:Build Scan 是分析 AGP 构建性能的首选工具。拿到它,你就不再需要靠猜来优化构建速度了。