编译优化
编译速度一直是开发过程中的诟病,严重影响开发效率。因此提升编译速度迫在眉睫,本文主要是通过Gradle配置实现优化目的
优化效益
- 提高开发效率
- 提升开发体验
Gradle配置优化
升级Gradle及Plugin
风险项:Gradle升级必会导致项目编译失败,需做相应适配
Gradle每次大版本升级都会带来性能的提升,这是构建工具之外无法做到的,条件允许情况下第一步要升级Gradle及Plugin版本
升级Java
Gradle运行在Java虚拟机(JVM)上,Java性能提升也有利于Gradle的编译
增大AS运行内存
- -Xms256m:初始堆内存
- -Xmx2048m:最小堆内存,可改为-Xmx4096m
在AS底部工具栏右键勾选Memory Indicator可查看内存信息
AS安装目录 -> bin -> studio64.exe.vmoptions
gradle.properties配置
# 开启守护进程,开启后Gradle不仅可以更好的缓存构建信息,且会运行在后台,避免每次构建都先初始化再启动JVM
org.gradle.daemon=true
# 开启并行编译,Gradle默认一次执行一个Task(串行),可通过配置让其并行执行Task,从而提升构建效率,缩短构建时间
org.gradle.parallel=true
# 启用配置缓存,Gradle6.6以后新增功能,若无构建配置发生变化(例构建脚本),Gradle会直接跳过配置阶段,从而提升编译速度
org.gradle.unsafe.configuration-cache=true
# 启用构建缓存,同一Task输入不变时,Gradle会直接检索缓存输出,不用再次执行该Task,从而提升编译速度
org.gradle.caching=true
# 使用非传递R类,Gradle8.0.0及之后版本默认开启。开启后,module中定义的资源不会在依赖该module的模块R.class中生成引用。引用module资源时需全路径引入
android.nonTransitiveRClass=true
# JVM配置,调整内存堆大小并使用并行垃圾回收器
# org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8 -XX:+UseParallelGC
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -XX:+UseParallelGC
# 停用Jetifier标志,support转为AndroidX的工具,当前项目都已适配AndroidX,可关闭,从而提高性能
android.enableJetifier=false
# 启用K2,kotlin 1.9.20中K2已是beta版本,可开启使用
kotlin.experimental.tryK2=true
build.gradle.kts优化
- KSP代替kapt
- kapt是kotlin注解处理器,运行速度比Kotlin Symbol Processor(KSP)慢很多
// project -> build.gradle.kts
plugins {
id("com.android.application") version "8.2.1" apply false
id("org.jetbrains.kotlin.android") version "1.9.22" apply false
id("com.android.library") version "8.2.1" apply false
// 启用KSP,与kotlin版本需对应
id("com.google.devtools.ksp") version "1.9.22-1.0.16" apply false
}
// module -> build.gradle.kts
// 导入plugin_version依赖类
import com.dcxing.plugin.version.*
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
// 导入plugin_version插件
id("com.dcxing.plugin.version")
// 启用KSP
id("com.google.devtools.ksp")
}
android {
...
}
dependencies {
implementation(Lib.core_ktx)
implementation(Lib.appcompat)
// KSP注解处理比kapt更快"com.github.bumptech.glide:ksp:4.16.0"
ksp(Lib.glide_ksp)
...
}
- 优化依赖关系
- 删除无用依赖
- 调整仓库地址顺序
- 固定依赖版本
// settings.gradle.kts
/**
* Gradle解析时,默认按配置中声明的仓库地址顺序检索,为减少检索时间,合理调整依赖仓顺序
* 国内镜像 > google() > mavenCentral() > other
*/
repositories {
// 阿里云https://juejin.cn/post/6907479665305190408
maven { url 'https://maven.aliyun.com/repository/public/' }
google()
mavenCentral()
maven { setUrl("https://jitpack.io") }
...
}
// module -> build.gradle.kts
// 若使用动态或快照版本,调整检索新版本时间(默认24h检索一次)
configurations.all {
// 动态版本缓存时效
resolutionStrategy.cacheDynamicVersionsFor(120, "minutes")
// 快照版本缓存时效
resolutionStrategy.cacheChangingModulesFor(24, "hours")
}
- 资源优化
- devDebug版本,更优的调试效率无需太多资源(例多语言、多屏幕密度),指定一个即可
- 图片使用Webp格式
选中图片 -> 右键 -> Convert to WebP...或 使用svg矢量图
webp是一种支持有损压缩与透明度的图片格式,比jpg、png有更好的压缩效果
svg是与分辨率无关的矢量图,它会占用更少的资源
- 禁用res/drawable/下图片资源无损压缩
// app -> build.gradle.kts
android {
buildTypes {
release {
...
}
debug {
// debug构建时禁用res/drawable/图片自动压缩功能,提高编译速度
isCrunchPngs = false
...
}
}
// 多渠道打包指定资源
flavorDimensions.add("app")
productFlavors {
create("dev") {
dimension = "app"
// 指定资源
resourceConfigurations.add("en")
resourceConfigurations.add("xxhdpi")
}
...
}
}
- 慎用动态配置项
多渠道打包时往往会使用动态的aab文件名,每次编译都会动态获取影响编译速度,debug开发阶段可关闭动态配置项
- 动态apk文件名:包含动态构建时间、渠道名...
val buildTime: String = SimpleDateFormat("yyMMdd").format(Date().time)
使用离线的Gradle插件
- 修改gradle-wrapper.properties
减少参与编译文件
- 资源文件
- 代码文件
通过aar依赖,减少参与编译代码,从而提高构建速度