Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystify and Optimize Your Android Gradle Builds - Mobiconf 2021

4ce0d60e368cef89450f1d9dfdcb493f?s=47 Nate Ebel
October 07, 2021

Demystify and Optimize Your Android Gradle Builds - Mobiconf 2021

Gradle and the Android Gradle Plugin are the backbone of most Android projects today. They are also the source of much frustration for dev teams wishing their builds were faster or easier to work with.

This talk aims to demystify your Android build by helping you understand how Gradle works, what happens when you build your project, and how to start optimizing your build for increased developer productivity.

During this talk, we’ll focus on a few key areas including
- The difference between Gradle and Android Gradle Plugin
- What happens when you run a Gradle task
- How to investigate your project’s build performance
- Performance optimizations

By the end of the talk, you should better understand what happens when you build your Android app, and be equipped to start optimizing your builds for faster builds and happier developers.

4ce0d60e368cef89450f1d9dfdcb493f?s=128

Nate Ebel

October 07, 2021
Tweet

Transcript

  1. DEMYSTIFY & OPTIMIZE YOUR ANDROID GRADLE BUILDS

  2. Mobiconf 2021 Demystify & Optimize Your Android Gradle Builds Android

    Developer & Instructor Kotlin GDE @n8ebel goobar.dev Nate Ebel
  3. What is Gradle?

  4. What is Gradle? A. The source of 94.3% of Android

    dev Twitter tra ffi c B. A viable means of heating a small room C. A general purpose build tool used for Android and other projects D. All of the above
  5. What is Gradle? A. The source of 94.3% of Android

    dev Twitter tra ffi c B. A viable means of heating a small room C. A general purpose build tool used for Android and other projects D. All of the above
  6. Android Builds Android Gradle Plugin Gradle

  7. Android Builds Android Gradle Plugin Gradle

  8. Android Builds Gradle & the Android Gradle Plugin are the

    backbone of most Android projects today
  9. Android Builds Backbone of our Android projects

  10. Android Builds Backbone of our Android projects

  11. Android Builds Backbone of our Android projects Source of frustration

    and lost productivity
  12. Builders want to Build

  13. Developer Productivity Engineering

  14. Developer Productivity Engineering “The use of data analytics and build

    acceleration technologies to speed up critical software development processes - and to make them more e ff i cient.” https://gradle.com/blog/top-three-reasons-to-launch-a-dedicated-developer- productivity-engineering-team/
  15. Where are we going? Understanding Profiling Optimizing Maintaining

  16. My hope for you 1. Better understand what happens when

    you build your project 2. Identify at least 1 potential tool or optimization to try out today
  17. Understanding Your Build

  18. Run ‘app’ ?

  19. Executing tasks [:app:assembleDebug]

  20. Gradle Task “… a single atomic piece of work for

    a build, such as compiling classes or generating javadoc.” https://docs.gradle.org/current/dsl/org.gradle.api.Task.html
  21. Where do Tasks come from?

  22. Where to Tasks come from? • From Gradle • From

    our own custom Tasks • From Plugins
  23. Tasks coming from Gradle • help • dependencies • tasks

    • projects • properties
  24. Custom Gradle Tasks De fi ne your own tasks to

    perform whatever task you need Custom Tasks task clean(type: Delete) { delete rootProject.buildDir } task helloWorld { println("Hello World") }
  25. Tasks coming from Plugins • assembleDebug • artifactoryPublish • appDistributionUploadDebug

  26. Gradle Plugins “[… plugins add new tasks, domain objects, conventions,

    and extend core objects…]” https://docs.gradle.org/current/userguide/plugins.html
  27. Custom Gradle Plugins De fi ne your own Gradle plugins

    for common con fi guration or custom tasks Custom Tasks class VersionCodePlugin : Plugin<Project> { override fun apply(project: Project) { project.version = calculateVersion() … } } apply plugin: VersionCodePlugin
  28. What does the most basic Gradle project look like?

  29. The interesting functionality comes from Gradle Plugins

  30. What tasks are available in a brand new Android project?

  31. Android Gradle Plugin

  32. What is the relationship? Android Gradle Plugin Gradle

  33. Slow Builds?

  34. Slow builds come from • Underpowered hardware • Computationally intensive

    tasks • Building more than is needed
  35. Faster Machines == Faster Builds

  36. Avoid computationally intensive tasks when possible

  37. Avoid doing more work than is necessary

  38. Phases of Gradle Builds Initialization Configuration Execution

  39. Initialization

  40. Configuration

  41. Initialization & Configuration

  42. Execution

  43. Execution Task Input Output

  44. Task Execution Status • EXECUTED • UP-TO-DATE • FROM-CACHE •

    SKIPPED • NO-SOURCE
  45. Common Build Scenarios First Time Build Up-To-Date Build Clean Build

    Incremental Build
  46. First Time Build • Fresh checkout of a project •

    No previously built outputs/artifacts • May pull from a remote cache
  47. Up-To-Date Build • Run a task • Run the same

    task again with no changes • Ideally, nothing should run • Everything should be UP-TO-DATE
  48. Clean Build • Delete local build artifacts • Run your

    task again • May need to rebuild full project • Should ideally pull many artifacts from build cache
  49. Incremental Build • Make a change to your project code/resources

    • Run your task again • Ideally, only a portion of your project should need to rebuild
  50. Execute as few tasks as possible for any given build

  51. The Story So Far • Click ‘run app’ • Android

    Studio executes an Android Speci fi c Gradle task • That task comes from Android Gradle Plugin • That task will run via Gradle’s infrastructure • Gradle is designed to avoid doing unnecessary work • Our goal, then, is to con fi gure our builds to do as little work as possible
  52. Profiling Your Build

  53. What gets measured, gets improved

  54. Profiling/Monitoring Tools Gradle Build Output Android Studio Build Analyzer Gradle

    Buildscans Gradle Enterprise
  55. Gradle Build Output • Build time • Number of tasks

    executed • Number of tasks from cache • Number of tasks up-to-date • Task status
  56. Android Studio Build Analyzer • Build overview • Plugin analysis

    • Task execution time • Warnings & recommendations
  57. Profiling Across Machines

  58. Gradle Buildscans • Detailed report of a speci fi c

    build • Easily shareable between team members and across machines • Can extend to fi t the needs of your team
  59. Gradle Buildscans • Con fi guration, Initialization, and Execution time

    • Queryable build timeline • Console outputs • Project structure • Environment details • Cache hit/miss report • Test outputs
  60. How to Generate a Buildscan? • add --scan to the

    end of your Gradle Wrapper invocation • accept the TOS • click the generated link and enter an email • click the link in the email to view your scan • subsequent scans won’t require the email
  61. How can we use a Buildscan? • Analyze con fi

    guration and initialization times to ensure a properly con fi gured build • Analyze task execution to identify slow running tasks • Use the timeline to determine if any cacheable tasks were executed • Diagnose build failures for distributed teammates • Diagnose CI build failures • Identify hardware factors contributing to slow builds
  62. Analyzing Trends

  63. Gradle Enterprise

  64. Gradle Enterprise “Gradle Enterprise leverages acceleration technologies to speed up

    the software build and test process and data analytics to make troubleshooting more e ff i cient” https://gradle.com/
  65. What does Gradle Enterprise do? • Store buildscans on remote

    server for historical access and analysis • Automatically store buildscans in a single location • Provides a remote build cache • Analyze build trends over time • Enables support for custom tagging and fi ltering • Supports test distribution and analysis
  66. Gradle Enterprise at Premise • Identify build cache issues across

    local and CI builds • Identify regionally speci fi c build cache issues • Identify build speed regressions due to AGP and NDK • Quickly diagnose build failures for distributed team • Compare buildscans to diagnose build issues
  67. Gradle Enterprise at Premise • Is a paid product •

    Is an incredibly valuable tool for our team
  68. Optimizing Your Build

  69. Give your devs faster machines

  70. Slow build times * cost/dev = = money for faster

    hardware
  71. Enable build acceleration features

  72. • Parallel execution • Local build cache • Remote build

    cache • Con fi guration cache • File-system watching Build acceleration features
  73. Parallel Execution • Build projects in parallel • Very bene

    fi cial in multi-modular projects with reasonable dependency graph • Add org.gradle.parallel=true to gradle.properties
  74. Gradle Build Cache • Reuse the outputs from previous builds

    even after a clean • Local Cache • Add org.gradle.caching=true to your gradle.properties fi le • Remote Cache • Setup with, or without, Gradle Enterprise
  75. Configuration Caching • Cache con fi guration data • Add

    org.gradle.unsafe.con fi guration-cache=true to gradle.properties • Very experimental / Plugins must support it https://github.com/gradle/gradle/issues/13490
  76. File System Watching • Reduce I/O impact of builds using

    in-memory fi le system info • Add org.gradle.vfs.watch=true to gradle.properties • On by default in Gradle 7+
  77. Optimize memory settings

  78. Optimize memory settings • Allocate more memory to Gradle daemon

    • Add org.gradle.jvmargs=-Xmx2048M to gradle.properties • Allocate more memory to Kotlin compiler • Add -Dkotlin.daemon.jvm.options=-Xmx2048M to gradle.properties • Play with this setting based on your build and hardware
  79. Optimize memory settings • Remember that builds run in environments

    with limited resources • (Gradle daemon + Kotlinc) * numberOfSeparateBuildProcesses = total memory • Your machine, your teammate’s machine, and your CI machine might di ff er
  80. Optimize how you build

  81. Optimize how you build • Use a single JDK •

    Keep libraries and tooling up to date • Build only what is needed • Modularize your project • Reduce the use of kapt
  82. Use the same JDK • Use the same JDK for

    Android Studio and command line builds • Set JAVA_HOME environment variable • Con fi gure Android Studio to use that JDK rather than embedded • This will speed up builds when switching from cmd line & Android Studio
  83. Keep libraries up-to-date • Stay up to date with libraries,

    plugins, languages • Helps pick up performance improvements, cache miss fi xes, etc
  84. Build only what is needed • Don’t minify your app

    if you don’t need to • Don’t build multiple variants if you don’t need them all • Exclude locales/resources for dev builds when not needed • Disable plugins such as Crashlytics if not needed for dev builds • Build/test/analyze in parallel when possible
  85. Modularize your project • Modules/projects can build in parallel •

    Splitting your project into smaller modules enables greater parallelization • Limited bene fi t when most of the code is all in a single module • Limited bene fi t if all modules are highly coupled
  86. Reduce the use of kapt • Kapt is very slow

    for Kotlin builds • Avoid annotation processors with kapt if possible • Limit to speci fi c modules if possible • Consider using KSP if applicable for your project
  87. Maintaining Your Build

  88. Monitor and analyze your build

  89. Gradle Enterprise

  90. Gradle Doctor

  91. Gradle Doctor • Plugin to diagnose & prevent common build

    issues • Con fi gurable warnings for things such as • Build speed issues • Annotation processing time • Mismatched JDK versions • Building all variants • Remote cache speed issues https://runningcode.github.io/gradle-doctor/
  92. android-gradle-cache-fix Plugin

  93. android-gradle-cache-fix Plugin • Plugin to fi x known build cache

    issues in Android Gradle Plugin • Add to your project and start seeing more cache hits https://github.com/gradle/android-cache- fi x-gradle-plugin
  94. Benchmark your builds

  95. Gradle Profiler

  96. Gradle Profiler • Run multiple Gradle builds and aggregate the

    results • Highlights statistically signi fi cant changes to build performance • Use to pro fi le the impact of build changes such as enabling caching • Can be run manually or automated for common scenarios https://github.com/gradle/gradle-pro fi ler
  97. Gradle Profiler

  98. Keep your project up-to-date • Stay up to date with

    libraries, plugins, languages • Helps pick up performance improvements, cache miss fi xes, etc
  99. Make your build easier to work with

  100. Wrapping Up

  101. Android relies on Android Gradle Plugin and Gradle to build

    our projects
  102. Gradle provides infrastructure and plugins provide functionality

  103. There’s very little magic

  104. To speed up our builds, we can use faster hardware,

    do less intensive work, or do less work.
  105. Tools such as buildscans and Gradle Enterprise help diagnose build

    issues
  106. We can optimize our builds through caching, modularization, and other

    build acceleration strategies
  107. By monitoring and profiling performance, we may maintain efficiency over

    time
  108. Develop a culture of continued investment into developer productivity for

    happier, more productive, teams.
  109. Thank You @n8ebel goobar.dev