gradle构建项目速度优化及排查方式

文章目录

  • 一、前言
  • 二、Android项目优化
    • 1、相关配置
    • 2、构建速度分析
  • 三、Gradle项目通用优化
    • 1、分析构建耗时
    • 2、使用配置进行优化
    • 3、优化依赖解析
      • a. 避免不必要和未使用的依赖项
      • b. 优化存储库顺序
    • c. 最小化动态和快照版本
    • d. 通过构建扫描查找动态和变化的版本
    • e. 通过构建扫描可视化依赖关系解析
    • f. 删除或改进自定义依赖解析逻辑
    • g. 删除缓慢或意外的依赖项下载
    • 4、远程缓存
  • 四、参考链接

一、前言

gradle构建优化分为两部分,分别为Android上面的优化和gradle项目通用优化,使项目编译速度提升,节省开发时间。在此前提保持良好的编码习惯并减少代码和资源,也有利于提高编译速度。其中对于Android小型项目,Android官方提供的优化建议就足够了,过度优化有时候不见得能够提高构建速度。

二、Android项目优化

1、相关配置

这里根据官方文档整理后,将可以快速使用的配置记录如下:
app/build.gradle

android {defaultConfig {resourceConfigurations.addAll(["en", "xxhdpi"]) //限制资源版本}
}

gradle.properties

#在gradle高版本不再自动生成BuildConfig类,需要使用这个开启
android.defaults.buildfeatures.buildconfig=true
#使用非常量 R 类加速构建
android.nonFinalResIds=true
# 使用非传递 R 类方式加速构建
android.nonTransitiveRClass=true
android.useAndroidX=true
#如果项目都是androidX,可以把这个改为false,可以提高编译速度,但是编译会出警告,所以就不去掉了
android.enableJetifier=true
kotlin.code.style=official#-XX\:+UseParallelGC 使构建方式采用G1垃圾回收器。该配置对提高构建速度有明显效果
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding\=UTF-8 -XX\:+UseParallelGC#该配置可以启用缓存,对于第二次构建时候速度,效果明显,但是该功能属于测试功能,不支持所有插件,具体支持版本查看
#https://github.com/gradle/gradle/issues/13490
#不过对于Android官方插件一般都是支持的。
org.gradle.unsafe.configuration-cache=true
# Use this flag carefully, in case some of the plugins are not fully compatible.
org.gradle.unsafe.configuration-cache-problems=warn

对于除了gradle配置外,还有如图片采用webp格式,依赖库版本使用最新版本且是准确的版本号,避免使用'com.android.tools.build:gradle:2.+'需要匹配的版本号。将相关代码转换为库文件等等方式。
如果项目中使用了gradlePluginPortal()解析依赖需要将该依赖放在其余仓库后面。

因为Gradle 会按照声明的顺序搜索代码库,因此,如果先列出的代码库包含大多数插件,build 性能就会得到提升。因此,您可以尝试将
gradlePluginPortal() 条目放置在 settings.gradle
文件的代码库中最靠后的位置。在大多数情况下,这样可以最大限度地减少冗余插件搜索次数,并提高构建速度。

2、构建速度分析

这一个比较简单,基本上都源自官网

如需开始使用,请按以下步骤操作:

如果您尚未构建应用,请采用以下其中一种方法构建应用: 从菜单栏中依次点击 Build > Make Project。 如需构建
Android App Bundle 或 APK,请从菜单栏中依次点击 Build > Build Bundle(s) / APK(s) >
Build Bundle(s) 或 Build > Build Bundle(s) / APK(s) > Build APK(s)。
如需打开 Build 窗口,请从菜单栏中依次选择 View > Tool Windows > Build。 如需在 Build
Analyzer 中查看构建报告,请点击 Build 窗口中的 Build Analyzer 标签页。

编译完后如下
在这里插入图片描述

如需查看决定着构建时长的任务所属的插件的细分数据,请点击概览页面上的 Plugins with tasks impacting build
duration。您也可以从下拉菜单中选择 Tasks 并确认已选中 Group by plugin。 Build Analyzer
显示对构建时长影响最大的插件的详情。 任务窗格会显示为构建时长做出贡献的任务。任何有问题的任务旁边都会显示一个警告图标。

该图表显示了任务在总构建时长中所占的百分比。

详细信息窗格会详细描述针对所选任务已检测到的问题。

每个节点都会显示执行其直属子节点所用的总时长。时长有助于您重点检查对构建时长影响最大的任务。

点击Tasks impacting build duration后会发现整体构建时长
在这里插入图片描述
左侧的条目可以任意选择,如果有需要优化的地方会出现警告,如果没有则不会出现警告,如下是一个警告的内容
在这里插入图片描述
这个含义说的很明白了,这里就不再多说了,解决方式可以通过点击下面蓝色文字Click here to migrate your project to use non-transitive R classes进行解决,或者手动解决,在gradle.properties中添加如下内容

android.nonTransitiveRClass=true

修改完重新编译警告即可修复。不过有些无法解决,比如firebase的插件
在这里插入图片描述
类似于这种优化只能是做能力范围之内的优化,并非所有优化都能做到极致。
对于Build Analyzer工具的使用较为简单,多点一下不到一分钟即可学会所有功能,这里不再详细赘述。

处理完后第二次构建的速度大约是一秒

BUILD SUCCESSFUL in 951ms
110 actionable tasks: 2 executed, 108 up-to-date
Configuration cache entry reused.

这么快主要还是因为开启了缓存功能

三、Gradle项目通用优化

1、分析构建耗时

在项目下面执行命令

./gradlew build --scan

会对项目进行构建扫描,将各个地方的构建时间显示出来,详细程度远非Android官方提供的方式可比。构建完会显示一个链接,打开后输入邮箱会将构建结果发送到邮箱中,但是该方式会导致gradle的销售以及gradle广告也推送过来。打开后页面效果如下:
在这里插入图片描述

如果不想写邮箱可以使用简略版本

./gradlew --profile build

编译完成后,会在本地生成一个xml文档,地址会显示在最后一行。默认会在 build/reports/profile根项目的目录中生成 HTML 报告。页面如下
在这里插入图片描述
这两种方式使用都比较简单,不在赘述,因为大部分项目也不自己编写task,所以耗时基本上都是因为在执行系统函数,也无从优化,如果是复杂项目可以查看执行的哪个task,然后进行优化。例如
本项目的整体构建时间图例
在这里插入图片描述
整体耗时task为:app:mergeExtDexDebug

2、使用配置进行优化

通过添加以下代码可以快速提高项目编译速度
gradle.properties

#gradle独有构建优化
#开启并行构建
org.gradle.parallel=true
#启用守护进程,gradle3.4版本后默认开启
org.gradle.daemon=true
#启用配置缓存
org.gradle.configuration-cache=true
#启用构建缓存
org.gradle.caching=true

build.gradle

//将编译器作为单独的进程运行,该配置效果卓越,该配置的目的是将java类的编译放在独立进程进行操作,java类越多效果越明显
tasks.withType(JavaCompile).configureEach {options.fork = true
}

3、优化依赖解析

a. 避免不必要和未使用的依赖项

管理第三方库及其传递依赖项会显着增加项目维护成本和构建时间。
注意未使用的依赖项:当第三方库停止使用时,不会从依赖项列表中删除。这种情况在重构过程中经常发生。您可以使用Gradle Lint 插件 来识别未使用的依赖项。
如果您只使用第三方库中的少量方法或类,请考虑:
在您的项目中自己实现所需的代码
如果它是开源的,则从库中复制所需的代码(带有归属!)

b. 优化存储库顺序

当 Gradle 解析依赖项时,它会按声明的顺序搜索每个存储库。为了减少搜索依赖项所花费的时间,请首先声明托管最大数量依赖项的存储库。这最大限度地减少了解决所有依赖关系所需的网络请求数量。

c. 最小化动态和快照版本

动态版本(例如“2.+”)和更改版本(快照)迫使 Gradle 联系远程存储库以查找新版本。默认情况下,Gradle 仅每 24 小时检查一次。但您可以通过以下设置以编程方式更改此设置:
cacheDynamicVersionsFor
cacheChangingModulesFor
如果构建文件或初始化脚本降低了这些值,Gradle 会更频繁地查询存储库。如果您不需要每次构建时都使用依赖项的绝对最新版本,请考虑删除这些设置的自定义值。

d. 通过构建扫描查找动态和变化的版本

您可以通过构建扫描找到具有动态版本的所有依赖项:

./gradlew build --scan

'com.android.tools.build:gradle:2.+'类似的动态版本替换为准确版本'com.android.tools.build:gradle:2.3'

e. 通过构建扫描可视化依赖关系解析

在这里插入图片描述
构建扫描提供了另一种识别此问题的方法。您的构建应该在“项目配置”期间花费 0 秒来解决依赖关系。此示例显示构建在生命周期中过早地解决了依赖关系。您还可以在“性能”页面上找到“设置和建议”选项卡。这显示了在配置阶段解决的依赖关系。

f. 删除或改进自定义依赖解析逻辑

Gradle 允许用户以最适合他们的方式对依赖解析进行建模。简单的自定义(例如强制依赖项的特定版本或将一种依赖项替换为另一种依赖项)不会对依赖项解析时间产生太大影响。更复杂的自定义(例如下载和解析 POM 的自定义逻辑)可能会显着减慢依赖关系解析速度。

使用构建扫描或配置文件报告来检查自定义依赖项解析逻辑是否不会对依赖项解析时间产生不利影响。这可能是您自己编写的自定义逻辑,也可能是插件的一部分。

g. 删除缓慢或意外的依赖项下载

缓慢的依赖项下载可能会影响您的整体构建性能。有多种原因可能会导致这种情况,包括互联网连接速度慢或存储库服务器过载。在构建扫描的“性能”页面上,您将找到“网络活动”选项卡。此选项卡列出的信息包括:
下载依赖项所花费的时间
依赖下载的传输速率
按下载时间排序的下载列表
在以下示例中,两次缓慢的依赖项下载分别花费了 20 秒和 40 秒,并降低了构建的整体性能:
在这里插入图片描述

4、远程缓存

通过远程缓存可以将多人共同的项目缓存进行共用,这在协作开发中与本地缓存结合起来能大幅度节约开发时间,该远程缓存可以自己搭建缓存服务器,也可以使用gradle提供的收费的或者免费的缓存服务。关于远程缓存内容较为复杂,会在后续重新整理,暂时可查看以下链接
Build Cache
Build Cache Node User Manual。

四、参考链接

  1. 优化构建速度
  2. 使用 Build Analyzer 排查构建性能问题
  3. Inspecting Gradle Builds
  4. Build Cache
  5. Build Cache Node User Manual

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

⑤【Sorted Set】Redis常用数据类型: ZSet [使用手册]

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 目录 ⑤Redis Zset 操作命令汇总1. zadd 添加或…

[C/C++]数据结构 堆的详解

一:概念 堆通常是一个可以被看做一棵完全二叉树的数组对象,它是一颗完全二叉树,堆存储的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并且需要满足每个父亲结点总小于其子节点(或者每个父亲结点总大于其子节点) 堆可以分为两种: 小堆: 任意一个父亲节点都小于其子…

AIGC创作系统ChatGPT网站源码、支持最新GPT-4-Turbo模型、GPT-4图片对话能力+搭建部署教程

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

HarmonyOS应用开发者基础认证【满分答案】

系列文章 HarmonyOS应用开发者基础认证【闯关习题 满分答案】 HarmonyOS应用开发者基础认证【满分答案】 HarmonyOS云开发基础认证【最新题库 满分答案】 目录 系列文章一、判断题二、单选题三、多选题 一、判断题 在Column和Row容器组件中,justifyContent用于设置…

常见树种(贵州省):022绣线菊、月月青、金合欢、胡枝子、白刺花

摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、绣线菊…

100天精通Python(可视化篇)——第109天:Pyecharts绘制各种常用地图(参数说明+代码实战)

文章目录 专栏导读一、地图应用场景二、参数说明1. 导包2. add函数 三、地图绘制实战1. 省市地图2. 中国地图3. 中国地图(带城市)4. 中国地图(分段型)5. 中国地图(连续型)6. 世界地图7. 行程轨迹地图8. 人口…

WebUI自动化学习(Selenium+Python+Pytest框架)001

开启另一篇学习之路_WebUI自动化 先来一波基础概念 1.自动化适合什么类型的项目: 重复性高,迭代频率高的回归测试。数据量大、手工难以实现的压力测试,手工执行效率低的兼容测试 2.自动化的优点: 高效率、可重复、减少人为错误、克服手工测试的局限性 3.自动化…

光线追踪-Peter Shirley的RayTracingInOneWeekend系列教程(book1-book3)代码分章节整理

自己码完了一遍了,把代码分章节整理了一下,可以按章节独立编译,运行, 也可以直接下载编译好的release版本直接运行。 项目地址: Github: https://github.com/disini/RayTracingInOneWeekendChaptByChapt ​ ​ ​ ​

Rust语言入门教程(八) - 引用与借用

上一章的内容中我们讨论了Rust的所有权系统,当我们不想移动值的所有权时,我们可以使用引用和借用,而这正是本章想要讨论的问题。 引用(References) 引用允许你访问或修改数据而无需获取数据的所有权。在 Rust 中&…

阿里云MQTT: 子设备上线流程

0. 背景 阿里云网关子设备上平台的资料很少。有些厂家直接配置每个子设备的DeviceSecret到网关里,显然太麻烦了!我经过阅读阿里文档,发现有些简化的方法,更便于客户使用,因此分享给大家。 1. 主要信息片段 子设备 $…

基于springboot+mysql实现的小区物业管理系统

基于springbootmysql实现的小区物业管理系统,演示地址:登录 演示账号:用户名:744621980qq.com 密码:123456,主要包含房屋管理(楼栋管理,单元管理,房屋管理),车位管理,缴费管理,社区服务( 公告管理&#xf…

Linux socket编程(6):IO复用之select原理及例子

文章目录 1 五种I/O模型1.1 阻塞I/O模型1.2 非阻塞I/O模型1.3 I/O复用模型1.4 信号驱动I/O模型1.5 异步I/O模型 2 select函数3 select实战:实现多个套接字监听3.1 客户端3.2 服务端3.3 实验结果3.4 完整代码 在之前的网络编程中,我们遇到了一个问题&…

Qt TCP网络上位机的设计(通过网络编程与下位机结合)

目录 TCP 协议基础 QTcpServer 和 QAbstractSocket 主要接口函数 TCP 应用程序 1.服务端 2.客户端 上位机通过网络编程与下位机实现通信 TCP 协议基础 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于…

mysql从库设置为只读

直奔主题,mysql设置为只读后,无法增删改。 设置命令: mysql> set global read_only1; #1是只读,0是读写 mysql> show global variables like %read_only%; 以下是相关说明: 1、对于数据库读写状态&#xf…

详解RT-DETR网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署

论文地址:RT-DETR论文地址 代码地址:RT-DETR官方下载地址 目录 一、本文介绍 二、RT-DETR的网络结构 2.1、模型概览 2.2、高效混合编码器 2.3、IoU感知查询选择 2.4、 可扩展的RT-DETR 三、RT-DERT的环境搭建 四、免费数据集获取 五、获取RT-D…

爬楼梯(力扣LeetCode)动态规划

爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示…

使用python 实现华为设备的SFTP文件传输

实验目的: 公司有一台CE12800的设备,管理地址位172.16.1.2,现在需要编写自动化脚本,通过SFTP实现简单的上传下载操作。 实验拓扑: 实验步骤: 步骤1:将本地电脑和ensp的设备进行桥接&#xff…

菜单的hover不同动画背景

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧,主要包含CSS布局,CSS特效,CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点,CSS特效主要是一些动画示例,CSS花边是描述了一些CSS…

SWT/Jface(3): 表格中添加超链接

背景 实际业务中经常需要展示某个网站, 并且希望在展示的时候单击网站可直接访问, 本节演示在表格中如何添加超链接支持. 需求 假设我需要渲染一个Study类, 它只有三个属性id,name和website, 其中id只支持展示, name只支持编辑, 而website只支持单击时跳转到相应的网站, 效果…

Linux7设置ssh秘钥登录并关闭密码登录

说明:场景为windows使用WinScp远程登录linux服务 winscp安装教程:winscp安装及关联putty使用_putty.exe没有找到_cherishSpring的博客-CSDN博客 1.在window上生成公钥和秘钥,操作方式参考以下文章第3点: git关联云效使用教程_云…