开启并行构建时Gradle模块构建顺序是怎样的?拆分common模块能否提速?
Gradle模块拆分与编译速度优化相关问题解答
扁平化依赖能否提升编译速度
结论是拆分合理的前提下完全可以。
原本的金字塔依赖结构里,顶层的大体积common模块是所有下层模块的前置依赖,整个构建流程必须等这个大模块完全编译完成,才能开始编译下游的所有模块,相当于整个构建卡在了一个串行执行的大节点,多核CPU资源完全没法利用在这个阶段。
你把大common拆为多个无(或极少)互相依赖的顶层子模块后,只要开启了Gradle并行构建能力,这些没有依赖关系的顶层模块就可以被调度到多个CPU核心同时编译。而且不需要等所有公共模块编译完成,只要某一个顶层子模块编译完成,依赖它的下层模块就可以立刻启动编译,整个构建流程的并行度会显著提升,编译速度自然会更快。
Gradle是否会严格按照依赖顺序构建模块
Gradle一定会严格遵循依赖顺序执行任务,不存在跳过依赖提前构建上层模块的情况,这和无依赖模块并行构建并不冲突。
你了解到的任务树机制是完全正确的,Gradle的构建本质是执行一张有向无环图(DAG)结构的任务树,任意任务只有在它的所有依赖任务都执行完成之后,才会被调度执行。如果两个任务/模块之间不存在依赖链路,Gradle开启并行后就会同时调度这两个任务,完全不会互相干扰。
从任务树角度优化构建速度的可行方案
- 首先要打开Gradle并行构建开关,在项目根目录的
gradle.properties中添加配置org.gradle.parallel=true,这是利用多核能力的前提 - 拆分公共模块时尽量减少跨模块的依赖传递,避免拆分后依然出现多模块连环依赖,退化为串行构建结构
- 严格禁止模块间的循环依赖,循环依赖不仅会完全破坏并行构建能力,还会引发各种构建异常
- 配合开启Gradle构建缓存,在
gradle.properties中添加配置org.gradle.caching=true,修改单个公共子模块后,其他未改动的公共子模块可以直接复用缓存,不需要重新编译,提速效果会更明显 - 不要在模块的构建脚本中编写跨模块的任务引用,这类隐式依赖会导致Gradle无法正确识别任务依赖关系,不仅会导致并行构建出错,还会破坏构建缓存的有效性
内容的提问来源于stack exchange,提问作者the_prole
相关产品推荐
相关产品推荐

