23、构建性能优化:并行执行、配置优化、避免不必要的任务、使用分析报告
说实话,Gradle 项目一大了,构建速度慢得让人抓狂。我见过不少团队,每天等构建的时间比写代码还多。嗯,这其实不是 Gradle 的问题,而是我们没把它调教好。
今天咱们就聊聊怎么让 Gradle 跑得更快。说白了就四个方向:并行干活、少做无用功、配置别太啰嗦、用报告找瓶颈。
核心思路:构建优化的本质是「减少工作量」+「提高并行度」。别想着一步到位,先找到最慢的环节。
一、并行执行:让 CPU 别闲着
Gradle 默认是串行执行任务的。你想想看,一个项目有几十个模块,每个模块都要编译、测试、打包,如果一个个来,CPU 大部分时间都在空转。
开启并行构建,只需要在 gradle.properties 里加一行:
org.gradle.parallel=true
我个人习惯还会设置并行线程数:
org.gradle.workers.max=4
这个数字一般设成 CPU 核心数减 1 比较稳妥。我在项目中遇到过,设成 8 反而更慢——因为线程切换开销太大了。
小技巧:如果你不确定设多少合适,可以先不设 workers.max,Gradle 会自动根据 CPU 核心数来分配。
另外,按模块并行也很重要。如果你的项目是多模块结构,记得加上:
org.gradle.caching=true
这样不同模块之间可以并行构建,互不干扰。
二、配置优化:别在配置阶段做太多事
Gradle 的构建分三个阶段:初始化、配置、执行。很多人把耗时操作写在了配置阶段,结果每次运行 gradle tasks 都要等半天。
配置阶段应该只做声明,不做计算。比如:
// ❌ 错误做法:配置阶段执行耗时操作
allprojects {
task myTask {
doLast {
// 这里才真正执行
}
}
// 这里不要写耗时逻辑
}
// ✅ 正确做法:用 doLast 或 doFirst 延迟执行
allprojects {
task myTask {
doLast {
// 耗时操作放在这里
Thread.sleep(1000)
}
}
}
我曾经见过一个项目,配置阶段要跑 30 秒——因为有人在里面调用了远程 API。嗯,这其实是个设计问题。
另一个常见坑:在配置阶段读取文件。比如:
// ❌ 每次配置都读文件
def config = new File('config.json').text
// ✅ 用 Provider 延迟读取
def config = providers.fileContents('config.json').asText
注意:配置阶段的代码每次运行 Gradle 都会执行,哪怕你只是看看有哪些任务。所以一定要轻量。
三、避免不必要的任务:少做就是快
Gradle 的增量构建机制已经很智能了,但有些场景还是需要我们手动干预。
1. 使用 up-to-date 检查
Gradle 默认会检查任务的输入输出是否变化。如果没变,任务会被标记为 UP-TO-DATE,直接跳过。但有些自定义任务没做好声明,导致每次都重新执行。
task myTask {
inputs.file('input.txt') // 声明输入
outputs.file('output.txt') // 声明输出
doLast {
// 只有输入变化时才执行
}
}
2. 禁用不需要的任务
比如测试任务,如果只是打包,没必要跑测试:
gradle build -x test
或者在构建脚本里按条件禁用:
tasks.named('test') {
enabled = project.hasProperty('runTests')
}
3. 避免重复配置
我见过有人每个子模块都写一遍相同的依赖配置。其实用 subprojects 统一配置就好:
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.13.2'
}
}
避坑指南:我曾经在一个大项目里,每个模块都单独声明了 logback 依赖,版本还不一致。结果构建时反复下载不同版本的 jar 包,浪费了大量时间。统一管理依赖版本,用 BOM 或者 version catalog 都能解决。
四、使用分析报告:找到真正的瓶颈
优化之前,先要知道慢在哪里。Gradle 提供了 构建扫描 功能,能生成详细的分析报告。
启用方式很简单:
gradle build --scan
运行后会在终端输出一个链接,打开就能看到:
- 每个任务的耗时
- 配置阶段花了多久
- 哪些任务没有增量执行
- 依赖下载的耗时
我个人习惯每周跑一次构建扫描,看看有没有异常。有一次我发现某个任务的耗时突然从 2 秒变成了 20 秒,查了半天发现是有人在任务里加了 Thread.sleep(18000)——嗯,调试代码忘了删。
另一个好用的工具是 --profile:
gradle build --profile
它会在 build/reports/profile 目录下生成 HTML 报告,展示每个阶段的耗时分布。
建议:把构建扫描集成到 CI 里,每次构建都自动生成报告。这样团队里每个人都能看到构建的健康状况。
知识体系总览
下面这张图总结了本章的核心逻辑,你可以对照着检查自己的项目:
实战建议
说了这么多,我建议你从最简单的开始:
- 先加
org.gradle.parallel=true,看看构建时间有没有明显下降 - 跑一次
--scan,看看哪个任务最慢 - 针对最慢的任务,检查是不是配置阶段做了太多事
- 把不必要的测试、文档生成等任务跳过
优化是个持续的过程。别指望一次改完所有问题,每次改一点,慢慢积累,构建速度就会越来越快。
最后说一句:构建优化不是炫技,而是为了节省团队的时间。你省下的每一分钟,都是团队多出来的一分钟生产力。