当前位置: 首页 > news >正文

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

相关文章:

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

文章目录 一、前言二、Android项目优化1、相关配置2、构建速度分析 三、Gradle项目通用优化1、分析构建耗时2、使用配置进行优化3、优化依赖解析a. 避免不必要和未使用的依赖项b. 优化存储库顺序 c. 最小化动态和快照版本d. 通过构建扫描查找动态和变化的版本e. 通过构建扫描可…...

MSI Center,XBox从任务栏取消固定

1,设置查看方式中隐藏项目可见 2,进入文件夹:C:\Users\Default\AppData\Local\Microsoft\Windows\Shell 找到下面这两个文件夹: 3,修改文件名或者删除这两个文件即可...

1、postman的安装及使用

一、安装、登录 1.安装 下载地址 2.注册登录(保存云服务进度) 二、界面介绍 三、执行接口测试页面 请求页签: 1、params:当是get请求时,通过params传参 2、authorization:鉴权 3、headers&#xff1…...

VUE简易计划清单

目录 效果预览图 完整代码 效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…...

c++日志单例实现

为了使项目的所有日志都打印到同一个日志中&#xff0c;必须使得所有类使用同一个日志&#xff0c;因此将日志类实现为单例。 .h文件 #pragma once#include<fstream>class LogHablee { private:LogHablee(std::string& dbg_dir);LogHablee(const LogHablee&) …...

C/C++实现:找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和 某知名企业笔试题

目录 题目描述: 示例 1: 示例 2: 示例 3: 提示: 思路:...

Qt实现绘制自定义形状

先创建一个继承自QWidget的控件&#xff1a; class MyPainterWidget:public QWidget 重写各种鼠标方法&#xff1a; protected:void paintEvent(QPaintEvent *) override;void mousePressEvent(QMouseEvent *e) override; //按下void mouseMoveEvent(QMouseEvent *e) …...

WordPress安装AWS插件实现文本转语音功能

适用于 WordPress 的 AWS 插件示例演示了内容创建者如何轻松地为所有书面内容添加文本转语音功能。随着语音搜索的不断增加&#xff0c;以音频格式提供更多网站内容变得至关重要。通过添加语音功能&#xff0c;网站访客可以通过在线音频播放器和播客应用程序等新渠道使用您的内…...

87-96-多维动态规划、技巧

LeetCode 热题 100 文章目录 LeetCode 热题 100多维动态规划87. 中等-不同路径88. 中等-最小路径和89. 中等-最长回文子串90. 中等-最长公共子序列91. 困难-编辑距离 技巧92. 简单-只出现一次的数字93. 简单-多数元素94. 中等-颜色分类95. 中等-下一个排列96. 中等-寻找重复数 …...

NX二次开发UF_CURVE_ask_wrap_curve_parents 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_wrap_curve_parents Defined in: uf_curve.h int UF_CURVE_ask_wrap_curve_parents(tag_t curve_tag, tag_t * defining_face, tag_t * defining_plane, tag_t * defin…...

使用 HTML、CSS 和 JavaScript 创建图像滑块

使用 HTML、CSS 和 JavaScript 创建轮播图 在本文中&#xff0c;我们将讨论如何使用 HTML、CSS 和 JavaScript 构建轮播图。我们将演示两种不同的创建滑块的方法&#xff0c;一种是基于opacity的滑块&#xff0c;另一种是基于transform的。 创建 HTML 我们首先从 HTML 代码开…...

ubuntu环境删除qtcreator方法

文章目录 方法1方法2方法3参考不同的安装方法,对应不同的删除方法 方法1 apt-get或者dpkg 方法2 QtCreatorUninstaller 方法3 MaintenanceTool...

软件测试基础知识

软件测试基本概念 1、软件程序文档&#xff0c;软件测试程序测试文档测试。 “程序”是指能够实现某种功能的指令的集合&#xff0c;“文档”是指软件在开发、使用和维护过程中产生的图文集合。&#xff1b; 2、软件的分类 按功能分&#xff1a;系统软件、应用软件 按技术架构分…...

使用 .toISOString() 方法生成当前时间的ISO格式字符串,解决UTC时区差问题

方法分析&#xff1a; 日常开发中&#xff0c;有时我们需要向后端传递的时间值可能并非一个时间对象&#xff0c;而是字符串格式。 例 1&#xff1a;[2023-08-16T08:07:25.577Z] 但是我们通过 new Date() 之后直接使用 .toString() 方法得到的却并非这种格式。 例 2&#xff1…...

“BMP转PNG一键转换,批量处理图片,迈入高效图片管理新时代“

你是否曾经为了转换图片格式而烦恼&#xff1f;是否曾经因为一张一张地手动转换而感到无奈&#xff1f;现在&#xff0c;我们的全新工具将为你解决这些问题&#xff0c;开启高效图片管理新时代&#xff01; 首先&#xff0c;我们进入首助编辑高手主页面&#xff0c;会看到有多种…...

解决Vue编程式导航路由跳转不显示目标路径问题

我们配置一个编程式导航的路由跳转&#xff0c;跳转到 /search 页面&#xff0c;并且携带categoryName和categoryId两个query参数。 this.$router.push({path: "/search",query: {categoryName: dataset.categoryname,categoryId: dataset.categoryid} }) 如果我们…...

Android studio 引用framework.jar

framework.jar 引用目录 N/O&#xff1a; out/target/common/obj/JAVA_LIBRARY/framework_interminate/classes.jarAndroid 9/10: out/soong/.intermediates/frameworks/base/framework/android_common/combined/framework.jarAndroid 11: out/soong/.intermediates/framewo…...

软著项目推荐 深度学习 python opencv 火焰检测识别 火灾检测

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…...

宝塔面板安装搭建DiscuzQ论坛教程与小程序上架发布后的展示效果

DiscuzQ论坛小程序上架发布后的展示效果&#xff1a; 1、需要用到的环境&#xff1a; php7.2 mysql5.7或者MariaDB 10.2(我安装用的mysql8.0) php除了必要的一些扩展外&#xff0c;还需要启用readlink、symlink函数等&#xff0c;具体看官方说明&#xff0c;安装的时候也会提醒…...

交换机配置与管理

文档以国产迈普交换机为例&#xff0c;各厂家交换机配置有少许不同&#xff0c;仅供参考。 交换机命令行模式&#xff1a; 普通用户模式Hostname>&#xff08;&#xff09; exit 输入enable命令 特权用户模式Hostname#&#xff08;&#xff09; exit 输入configu…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

第14节 Node.js 全局对象

JavaScript 中有一个特殊的对象&#xff0c;称为全局对象&#xff08;Global Object&#xff09;&#xff0c;它及其所有属性都可以在程序的任何地方访问&#xff0c;即全局变量。 在浏览器 JavaScript 中&#xff0c;通常 window 是全局对象&#xff0c; 而 Node.js 中的全局…...