Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Gradle build: The time is now
Search
Alexey Bykov
January 25, 2023
Programming
2
880
Gradle build: The time is now
Alexey Bykov
January 25, 2023
Tweet
Share
More Decks by Alexey Bykov
See All by Alexey Bykov
How we boosted ExoPlayer performance by 30%
nonews
0
48
Improving Video Playback with ExoPlayer
nonews
0
930
Where and how to run UI tests (Droidcon London, 2021)
nonews
0
630
Where and how to run UI tests (Droidcon Lisbon & Android Makers, Paris)
nonews
0
290
RxJava in a nutshell
nonews
0
270
Где и как прогонять UI тесты
nonews
0
360
Давайте обращать внимание на детали? (Gorod.it, Томск, 10.11.19)
nonews
0
94
Other Decks in Programming
See All in Programming
fs2-io を試してたらバグを見つけて直した話
chencmd
0
230
103 Early Hints
sugi_0000
1
230
Beyond ORM
77web
5
520
HTTP compression in PHP and Symfony apps
dunglas
2
1.7k
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
730
競技プログラミングへのお誘い@阪大BOOSTセミナー
kotamanegi
0
360
nekko cloudにおけるProxmox VE利用事例
irumaru
3
430
「Chatwork」Android版アプリを 支える単体テストの現在
okuzawats
0
180
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
Go の GC の不得意な部分を克服したい
taiyow
2
770
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
240
17年周年のWebアプリケーションにTanStack Queryを導入する / Implementing TanStack Query in a 17th Anniversary Web Application
saitolume
0
250
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
The Invisible Side of Design
smashingmag
298
50k
BBQ
matthewcrist
85
9.4k
For a Future-Friendly Web
brad_frost
175
9.4k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
A Tale of Four Properties
chriscoyier
157
23k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
Transcript
GRADLE BUILD: The time is now Alexey Bykov
2 Alexey Bykov Senior Software Engineer 6 years Google Developer
Expert @nonewsss
Dad what's that dark place over there?
Goals Feel comfortable about
Goals Feel comfortable about Improve build time
6 Build time. Why?
7 Such sample not applies to Reddit or any other
company I may worked at Build time. Why? ~ 10 engineers ~ 12 m ~ 20 builds (daily)
8 Such sample not applies to Reddit or any other
company I may worked at Build time. Why? ~ 1000 builds ~ 200 h Weekly ~ 10 engineers ~ 12 m ~ 20 builds (daily)
9 ~ 200 h
10 Gradle starter
11 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
12 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
13 What is a build?
14 Build Sequence of steps to transform source code
to a final product Step Step Step binary Src
15 Steps == Tasks Task Task Task binary Src
16 Tasks can be asynchronous Task Task Task binary Src
17 Input & output Task
18 Input & output Task @Input @InputFiles Input
19 Input & output Task @Input @TaskAction @InputFiles Input
20 Input & output Task @Input @OutputDirectory @TaskAction @InputFiles Input
Output
21 JavaCompile Java Version Example
22 Example JavaCompile Java Version Source code
23 Example JavaCompile Java Version Source code Compiler args Class
files
24 Tasks can be dependant Task Task Task Input Output
Output Output
25 Tasks can be cacheable Task @CacheableTask Input Output
26 Tasks can be cacheable Task Input Output Cache @CacheableTask
27 Tasks labels
28 BUILD SUCCESSFUL in 6m 49s 7960 actionable tasks: 130
executed, 371 from cache, 7459 up-to-date Tasks labels
29 BUILD SUCCESSFUL in 6m 49s 7960 actionable tasks: 130
executed, 371 from cache, 7459 up-to-date Tasks labels
30 UP-TO-DATE Incremental cache applied
31 FROM CACHE Build cache applied
32 SKIPPED Excluded explicitly or has predicate
33 NO SOURCE Can’t be executed, as there is
no code
34 EXECUTED (NO LABEL) Task run its action
35 Task sources — Build script (kts/groovy) — Build Src
— External (like plugin)
36 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
37 Project — Main Gradle API — Set of the
tasks — 1 to 1 dependency with build.gradle
38 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
39 Plugins — Configuration of settings and tasks
40 Plugins — Configuration of settings and tasks — Example:
* Android Gradle Plugin (AGP) * Kotlin Gradle Plugin (KGP)
41 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
42 Build Lifecycle 1. Configuration What to do? (Configure tasks)
43 1. Configuration What to do? (Configure tasks) Build Lifecycle
2. Execution Tasks
44 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
Caching Gradle Daemon JVM process
Caching Gradle Daemon JVM process * Long-running process
Caching Gradle Daemon JVM process * Long-running process *
Enabled by default
Caching Gradle Daemon JVM process * Long-running process *
Enabled by default * Not stable on the CI
Caching Gradle Daemon JVM process * Long-running process *
Enabled by default * Not stable on the CI org.gradle.daemon=false #gradle.properties
Caching Gradle Daemon JVM process In memory
Caching Configuration cache
Caching Configuration cache * Experimental
Caching Configuration cache * Experimental * project/.gradle/configuration-cache
Caching Configuration cache * Experimental * project/.gradle/configuration-cache * Works
based on input/output principle
Caching Gradle Daemon JVM process Configuration cache In
memory In project
Caching Incremental cache
Caching Incremental cache * Short-term cache
Caching Incremental cache * Short-term cache * Stores in
build folders
Caching Incremental cache * Short-term cache * Can be
easily invalidated * Stores in build folders
Caching In memory In project Gradle Daemon JVM process
Configuration cache Incremental cache
Caching Build cache
Caching Build cache * Long-term cache
Caching Build cache * Long-term cache * ~.gradle/caches/build-cache1/
Caching
65 Example JavaCompile Java Version Source code Compiler args Class
files
66 Example $hash $hash $hash Java Version Source code Compiler
args
67 Example $hash $hash $hash CacheKey
68 Example $hash $hash $hash CacheKey ffb08d41a85389bbbe6e8bbe480f0560
Build cache
70 Example $hash $hash $hash CacheKey Build cache
71 Example $hash $hash $hash CacheKey Build cache
72 Example $hash $hash $hash CacheKey Build cache JavaCompile
Class files
Build cache Each CacheKey in build-cache is a compressed
byte-code
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache
Caching Dependency cache
Caching Dependency cache * .jars or *.aars
Caching Dependency cache * .jars or *.aars ~./gradle/cache/modules-2
Caching In memory In project Out project Gradle Daemon
JVM process Configuration cache Incremental cache Build cache Dependency cache
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache Remote
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache Build cache Remote
Remote caching Build cache Stores on remote server
Remote caching Build cache Stores on remote server Copies
to the local cache
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache Build cache Remote
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache Build cache Proxy Remote
Jitpack was down for ~2 days https://github.com/jitpack/jitpack.io/issues/5337
Remote Caching Proxy Your own maven
Remote Caching Proxy Your own maven Which syncs data
Caching Local In memory In project Out project Gradle
Daemon JVM process Configuration cache Incremental cache Build cache Dependency cache Build cache Proxy Remote
90 Cache:Conslusion
91 Incremental applied Incremental cache Input Action
92 Incremental applied Incremental cache Input Action UP-TO-DATED
93 Incremental applied Incremental cache Input Action
94 Build cache applied Incremental cache Input Action Build Cache
FROM-CACHE
95 No cache Incremental cache Input Action Build Cache
96 No cache Incremental cache Input Build Cache NO LABEL
Action
97 Gradle starter Tasks Plugins Projects Build Lifecycle Caching Properties
98 Properties File to easily configure Gradle
99 Properties File to easily configure Gradle Can be: ~./gradle.properties
Project/gradle.properties
100 Properties File to easily configure Gradle Can be: ~./gradle.properties
Project/gradle.properties Gradle merge them
101 Properties File to easily configure Gradle Can be: ~./gradle.properties
Project/gradle.properties Gradle merge them Global > Local
102 Measure!
103
104 Measure! Locally?
105 Measure! Locally? * Manually? * Automatically?
106 Measure! Locally? * Manually? * Automatically? CI?
107 Measure! Locally? * Manually? * Automatically? CI? * Incremental?
108 Measure! Locally? * Manually? * Automatically? CI? * Incremental?
* Clean build?
109 Measure! Locally? * Manually? * Automatically? CI? * Incremental?
* Clean build? Where to send?
110 Measure! Locally? * Manually? * Automatically? CI? * Incremental?
* Clean build? Where to send? HOW???
111 1. Locally
112 1. Locally ~ daily, on a laptop
113 1. Locally ~ daily, on a laptop ~ incremental
build
114 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes
115 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes ~ clean build
116 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes ~ clean build ~ configuration
117 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes ~ clean build ~ no external monitor ~ configuration
118 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes ~ clean build ~ no external monitor ~ no android studio ~ configuration
119 1. Locally ~ daily, on a laptop ~ incremental
build ~ incremental changes ~ clean build ~ no external monitor ~ no android studio ~ cli ~ configuration
120 Collect automatically
121 Collect automatically ~ Only if you have > 20
engineers
122 Collect automatically ~ Only if you have > 20
engineers ~ Tool: Talailot https://github.com/cdsap/Talaiot
123 2. CI
124 2. CI Do it together with local measurement
125 3. How?
126 3. How? ~ Build Scan
127 3. How? ~ Build Scan Most powerful Good visualisation
Shares build outside
128 3. How?
129 3. How? ~ Build Scan ~ Gradle profiler
130 Gradle profiler https://github.com/gradle/gradle-profiler ~ brew install gradle-profiler
131 Scenario no_op { tasks = [“assembleDebug"] } #incremental
132 Scenario #build cache clean_no_op { tasks = ["clean", "assembleDebug"]
} no_op { tasks = [“assembleDebug"] } #incremental
133 Scenario #build cache clean_no_op { tasks = ["clean", "assembleDebug"]
} no_op { tasks = [“assembleDebug"] } #incremental incremental_changes { tasks = ["assembleDebug"] apply-abi-change-to = “sample/src/main/…TeamsViewModel.kt” }
134 Scenario no_op { tasks = [“assembleDebug"] } clean_no_op {
tasks = ["clean", "assembleDebug"] } incremental_changes { tasks = ["assembleDebug"] apply-abi-change-to = "sample/src/main/java/com/alexbykov/oknetwork/data/TeamsViewModel.kt" } #incremental #build cache #incremental changes
135 Scenario gradle-profiler --benchmark \ --scenario-file profiler-scenario
136 Scenario gradle-profiler --benchmark \ --scenario-file profiler-scenario \ --measure-config-time
137 Output
138 CSV
139 Configuration time
140 After ~ Parse it
141 After ~ Parse it ~ Send it to somewhere..
142 Somewhere ~ Influx db
143 Somewhere ~ Influx db ~ Elastic search
144 Somewhere ~ Influx db ~ Elastic search ~ Graphite
…… or…
145 Google sheet
146 Google sheet + Forms ~ Link sheet with forms
147 Google sheet + Forms ~ Link sheet with forms
~ Know form ids and send shorturl.at/mzNOY
148 Let’s improve!
149 Disable Jetifier
150 Disable Jetifier ~ appsupport -> androidx
151 Disable Jetifier ~ appsupport -> androidx ~ ./gradlew checkJetifier
152 gradle.properties android.enableJetifier=false
153 Non-Transitive R classes
154 Problem app feature1 Feature3 feature2
155 Problem app feature1 Feature3 feature2 R class R class
R class R class
156 Content merging app feature1 Feature3 feature2 R class (app,
f1,f2,f3) R class (f2, f3) R class (f2, f3) R class (f1)
157 Non-transitive app feature1 Feature3 feature2 R class (f2) R
class (f3) R class (app) R class (f1)
158 Non-transitive ~ R.strings -> YourModule.R.strings ~ All resources
159 gradle.properties android.nonTransitiveRClass=true shorturl.at/gK567
160 Virtual file system
161 Virtual file system shorturl.at/bzIJO org.gradle.vfs.watch=true
162 Don’t use buildSrc folder
163 ~ KTS & Dependency Most common use-case
164 Problems ~ Incremental cache invalidated
165 ~ Build cache invalidated Problems ~ Incremental cache invalidated
shorturl.at/eruJM NO LABEL
166 Version Catalog shorturl.at/oxY02
167 Version Catalog ~ No cache issues
168 Version Catalog ~ No cache issues ~ .toml file
(can be standalone)
169 Version Catalog ~ No cache issues ~ Bundling dependencies
~ .toml file (can be standalone)
170 Version Catalog [versions] groovy = "3.0.5" checkstyle = "8.37"
171 Version Catalog [libraries] groovy-core = { module = "org.codehaus.groovy:groovy",
version.ref = "groovy" } groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" } [versions] groovy = "3.0.5" checkstyle = "8.37"
172 Bundling [bundles] groovy = ["groovy-core", "groovy-json", "groovy- nio"]
173 Bundling [bundles] groovy = ["groovy-core", "groovy-json", "groovy-nio"] implementation libs.groovy
174 Focus plugin
175 Focus plugin shorturl.at/hioEM ~ Allows to manage settings.gradle
176 Focus plugin ~ Allows to manage settings.gradle ~ Mostly
useful in monorepo shorturl.at/hioEM
177 Java version
178 Java version ~ Have Java 8? —> Java 11
179 Java version ~ Have Java 8? —> Java 11
~ Have Java 11 —> A/B tests & experiments
180 Tune gradle properties
181 Tune gradle properties ~ Always do A/B tests with
GC -XX:+UseParallelGC -XX:+UseG1GC (default)
182 Tune gradle properties ~ Always do A/B tests with
GC ~ A/B tests with heap size org.gradle.jvmargs=-Xmx..G kotlin.daemon.jvmargs=-Xmx..g
183 Tune gradle properties ~ Always do A/B tests with
GC ~ A/B tests with heap size ~ Choose proper one for you 1. Kotlin daemon > Gradle Daemon 2. Kotlin daemon < Gradle Daemon 3. Kotlin daemon == Gradle Daemon
184 Some ideas to test android.disableAutomaticComponentCreation=true android.defaults.buildfeatures.buildconfig=false android.defaults.buildfeatures.aidl=false android.defaults.buildfeatures.renderscript=false android.defaults.buildfeatures.resvalues=false
android.defaults.buildfeatures.shaders=false
185 Never apply new properties without testing!
186 kapt —> KSP
187 kapt —> KSP ~25% No stubs generation
188 KSP Support ~ Room ~ Moshi ~ Glide ~
Hilt ~ Dagger2 ~ Anvil
189 Hilt problem
190 Hilt problem ~ Works based on subcomponents ~ Subcomponents
generates in parent component
191 Modularisation
192 Modularisation ~ api/impl
193 Modularisation ~ api/impl ~ Restrict merging to app module
194 https://github.com/danger/danger Danger!
195 Parallel
196 Parallel org.gradle.parallel=true
197 Parallel org.gradle.parallel=true Workers count == CPU cores
198 Apply configuration cache
199 Configuration cache org.gradle.unsafe.configuration-cache=true org.gradle.unsafe.configuration-cache-problems=warn shorturl.at/buUVZ
200 Configuration time 3 minutes ~10 seconds Before After
201 Project isolation (future)
202 Project isolation (future) shorturl.at/gyJRV org.gradle.unsafe.isolated-projects=true
203 Build Cache
204 Build Cache org.gradle.caching=true
205 Remote build cache shorturl.at/LQT17
206 Remote build cache Remote Build cache Local machine
Mr CI
207 Remote build cache Remote Build cache Local machine
Mr CI Read/W rite
208 Remote build cache Remote Build cache Local machine
Mr CI Read/W rite Read
Preventing cache misses ~ shorturl.at/CMWZ7 ~ shorturl.at/EMNSU ~ shorturl.at/vY389
Build cache—fix plugin shorturl.at/ckls3
211 Gradle doctor plugin shorturl.at/abBOS
212 Gradle best practices shorturl.at/cjEQX
213 Other ~ Extract native to libraries ~ Don’t use
flavors and build variants ~ Always test an impact before merging ~ Use latest tools ~ Keep things under control
214 Gradle enterprise https://gradle.com/roi-calculator/
215 Official guides shorturl.at/dfhw2 shorturl.at/EGKQ4
216 Build time with all of this ~12 minutes ~2
minutes Before After
217 Learn Gradle https://gradle.com/training/ ~ Trainings: https://blog.gradle.org/how-gradle-works-1 ~ Gradle blog:
~ Jendrik Johannes: https://www.youtube.com/@jjohannes
218 Slides @nonewsss