编译优化

编译速度一直是开发过程中的诟病,严重影响开发效率。因此提升编译速度迫在眉睫,本文主要是通过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.20K2已是beta版本,可开启使用
kotlin.experimental.tryK2=true

build.gradle.kts优化

  1. 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)

    ...
}

  1. 优化依赖关系
  • 删除无用依赖
  • 调整仓库地址顺序
  • 固定依赖版本
// 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")
}

  1. 资源优化
  • 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")
        }

        ...
    }
}

  1. 慎用动态配置项

多渠道打包时往往会使用动态的aab文件名,每次编译都会动态获取影响编译速度,debug开发阶段可关闭动态配置项

  • 动态apk文件名:包含动态构建时间、渠道名…
val buildTime: String = SimpleDateFormat("yyMMdd").format(Date().time)

使用离线的Gradle插件

  • 修改gradle-wrapper.properties 在这里插入图片描述

减少参与编译文件

  • 资源文件
  • 代码文件通过aar依赖,减少参与编译代码,从而提高构建速度

如何学习性能优化

那么在针对性能优化这个点,特意给大家准备了这份《Android性能优化大厂实战全解析》里面包含了腾讯、百度、字节等大厂的性能优化实战,既能够夯实底层原理、性能调优等核心技术点,又能够掌握普通开发者,难以触及的架构设计方法论。让你在工作中、团队里、面试时,拥有同行难以复制的核心竞争力。

有需要学习资料的朋友,可以扫描下方二维码免费领取!!

在这里插入图片描述

腾讯团队

  • 腾讯Bugly—对字符串匹配算法的一点理解
  • 腾讯光影研究室—Android P之Smart Linkify
  • 腾讯Bugly—动态下发 so 库在 Android APK 安装包瘦身方面的应用
  • QQ音乐—彻底弄懂浏览器缓存策略
  • QQ音乐Android编译提速之路
  • 全民k歌适配arm64-v8a方案
  • 全民K歌内存篇1——线上监控与综合治理
  • 全民K歌内存篇2——虚拟内存浅析
  • 全民K歌内存篇3——native内存分析与监控

在这里插入图片描述

字节跳动团队

  • 字节跳动技术团队— 深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 字节跳动技术团队—二维码扫描优化
  • 字节跳动技术团队—深入理解gradle框架之二:依赖实现分析
  • 字节跳动技术团队—Scene:Android 开源页面导航和组合框架
  • 字节跳动技术团队—抖音包大小优化-资源优化
  • 字节跳动技术团队—AwCookieManager.nativeGetCookie crash 排查
  • 字节跳动技术团队—另类 BadTokenException 问题分析和解决
  • 字节跳动—Android Camera内存问题剖析
  • 抖音BoostMultiDex优化实践:Android低版本上APP首次启动时间减少80%
  • 抖音BoostMultiDex优化实践:Android低版本上APP首次启动时间减少80%(二)
  • 抖音 Android 性能优化系列:Java 内存优化篇

在这里插入图片描述

阿里团队

  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能
  • 支付宝 App 构建优化解析:Android 包大小极致压缩
  • 解决支付宝包体积优化的遗留问题:运行时获取dexpc
  • 闲鱼技术—曾梦想 if-else 走天涯?看看“责任树模式”优化
  • 闲鱼如何在2个月内实现Android启动速度翻倍的?
  • 高德技术—Android Native 内存泄漏系统化解决方案
  • 天猫精灵技术—史上最全Android渲染机制讲解(长文源码深度剖析)

在这里插入图片描述

百度团队

  • 百度APP-Android H5首屏优化实践
  • 百度App技术—一种简单优雅的TextView行间距适配方案
  • 百度App技术—Android 10分区存储介绍及百度APP适配实践
  • 百度App技术—Gradle 与 Android 构建入门
  • 百度App组件化之路
  • 百度App网络深度优化系列《三》弱网优化

  • 在这里插入图片描述

网易团队

  • 网易新闻客户端 H5 秒开优化
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”
  • 网易传媒技术团队—AOP技术在客户端的应用与实践
  • 网易大数据|互联网产品决策秘笈: AB测试

  • 在这里插入图片描述

美团团队

  • 美团技术团队—Android静态代码扫描效率优化与实践
  • 美团技术团队—Probe:Android线上OOM问题定位组件
  • 美团技术团队—移动端UI一致性解决方案
  • 美团—设计稿(UI视图)自动生成代码方案的探索
  • ……
    在这里插入图片描述
有需要完整性能优化完整学习资料的朋友,可以扫描下方二维码免费领取!!!
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐