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

Demystify and Optimize Your Android Gradle Builds - Mobiconf 2021

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.

Nate Ebel

October 07, 2021
Tweet

More Decks by Nate Ebel

Other Decks in Programming

Transcript

  1. DEMYSTIFY & OPTIMIZE
    YOUR ANDROID GRADLE
    BUILDS

    View full-size slide

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

    Kotlin GDE
    @n8ebel goobar.dev
    Nate Ebel

    View full-size slide

  3. What is Gradle?

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  6. Android Builds
    Android

    Gradle Plugin
    Gradle

    View full-size slide

  7. Android Builds
    Android

    Gradle Plugin
    Gradle

    View full-size slide

  8. Android Builds
    Gradle & the Android Gradle Plugin are the
    backbone of most Android projects today

    View full-size slide

  9. Android Builds
    Backbone of our Android projects

    View full-size slide

  10. Android Builds
    Backbone of our
    Android projects

    View full-size slide

  11. Android Builds
    Backbone of our
    Android projects
    Source of frustration
    and lost productivity

    View full-size slide

  12. Builders want to Build

    View full-size slide

  13. Developer Productivity Engineering

    View full-size slide

  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/

    View full-size slide

  15. Where are we going?
    Understanding Profiling
    Optimizing Maintaining

    View full-size slide

  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

    View full-size slide

  17. Understanding
    Your Build

    View full-size slide

  18. Run ‘app’ ?

    View full-size slide

  19. Executing tasks
    [:app:assembleDebug]

    View full-size slide

  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

    View full-size slide

  21. Where do Tasks come from?

    View full-size slide

  22. Where to Tasks come from?
    • From Gradle

    • From our own custom Tasks

    • From Plugins

    View full-size slide

  23. Tasks coming from Gradle
    • help
    • dependencies
    • tasks
    • projects
    • properties

    View full-size slide

  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")

    }

    View full-size slide

  25. Tasks coming from Plugins
    • assembleDebug
    • artifactoryPublish
    • appDistributionUploadDebug

    View full-size slide

  26. Gradle Plugins
    “[… plugins add new tasks, domain objects,
    conventions, and extend core objects…]”
    https://docs.gradle.org/current/userguide/plugins.html

    View full-size slide

  27. Custom Gradle Plugins
    De
    fi
    ne your own Gradle plugins for common con
    fi
    guration or custom tasks
    Custom Tasks
    class VersionCodePlugin : Plugin {

    override fun apply(project: Project) {

    project.version = calculateVersion()



    }

    }

    apply plugin: VersionCodePlugin

    View full-size slide

  28. What does the most basic
    Gradle project look like?

    View full-size slide

  29. The interesting
    functionality comes from
    Gradle Plugins

    View full-size slide

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

    View full-size slide

  31. Android Gradle Plugin

    View full-size slide

  32. What is the relationship?
    Android

    Gradle Plugin
    Gradle

    View full-size slide

  33. Slow Builds?

    View full-size slide

  34. Slow builds come from
    • Underpowered hardware

    • Computationally intensive tasks

    • Building more than is needed

    View full-size slide

  35. Faster Machines
    ==
    Faster Builds

    View full-size slide

  36. Avoid computationally intensive
    tasks when possible

    View full-size slide

  37. Avoid doing more work than is
    necessary

    View full-size slide

  38. Phases of Gradle Builds
    Initialization Configuration Execution

    View full-size slide

  39. Initialization

    View full-size slide

  40. Configuration

    View full-size slide

  41. Initialization & Configuration

    View full-size slide

  42. Execution
    Task
    Input Output

    View full-size slide

  43. Task Execution Status
    • EXECUTED
    • UP-TO-DATE
    • FROM-CACHE
    • SKIPPED
    • NO-SOURCE

    View full-size slide

  44. Common Build Scenarios
    First Time Build Up-To-Date Build
    Clean Build Incremental Build

    View full-size slide

  45. First Time Build
    • Fresh checkout of a project

    • No previously built outputs/artifacts

    • May pull from a remote cache

    View full-size slide

  46. 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

    View full-size slide

  47. Clean Build
    • Delete local build artifacts

    • Run your task again

    • May need to rebuild full project

    • Should ideally pull many artifacts from build cache

    View full-size slide

  48. 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

    View full-size slide

  49. Execute as few tasks as possible
    for any given build

    View full-size slide

  50. 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

    View full-size slide

  51. Profiling

    Your Build

    View full-size slide

  52. What gets measured, gets improved

    View full-size slide

  53. Profiling/Monitoring Tools
    Gradle Build Output
    Android Studio

    Build Analyzer
    Gradle Buildscans Gradle Enterprise

    View full-size slide

  54. Gradle Build Output
    • Build time

    • Number of tasks executed

    • Number of tasks from cache

    • Number of tasks up-to-date

    • Task status

    View full-size slide

  55. Android Studio Build Analyzer
    • Build overview

    • Plugin analysis

    • Task execution time

    • Warnings & recommendations

    View full-size slide

  56. Profiling Across Machines

    View full-size slide

  57. 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

    View full-size slide

  58. Gradle Buildscans
    • Con
    fi
    guration, Initialization, and Execution time

    • Queryable build timeline

    • Console outputs

    • Project structure

    • Environment details

    • Cache hit/miss report

    • Test outputs

    View full-size slide

  59. 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

    View full-size slide

  60. 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

    View full-size slide

  61. Analyzing Trends

    View full-size slide

  62. Gradle Enterprise

    View full-size slide

  63. 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/

    View full-size slide

  64. 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

    View full-size slide

  65. 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

    View full-size slide

  66. Gradle Enterprise at Premise
    • Is a paid product

    • Is an incredibly valuable tool for our team

    View full-size slide

  67. Optimizing

    Your Build

    View full-size slide

  68. Give your devs faster machines

    View full-size slide

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

    View full-size slide

  70. Enable build acceleration features

    View full-size slide

  71. • Parallel execution

    • Local build cache

    • Remote build cache

    • Con
    fi
    guration cache

    • File-system watching
    Build acceleration features

    View full-size slide

  72. 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

    View full-size slide

  73. 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

    View full-size slide

  74. 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

    View full-size slide

  75. 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+

    View full-size slide

  76. Optimize memory settings

    View full-size slide

  77. 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

    View full-size slide

  78. 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

    View full-size slide

  79. Optimize how you build

    View full-size slide

  80. 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

    View full-size slide

  81. 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

    View full-size slide

  82. Keep libraries up-to-date
    • Stay up to date with libraries, plugins, languages

    • Helps pick up performance improvements, cache miss
    fi
    xes, etc

    View full-size slide

  83. 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

    View full-size slide

  84. 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

    View full-size slide

  85. 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

    View full-size slide

  86. Maintaining

    Your Build

    View full-size slide

  87. Monitor and analyze your build

    View full-size slide

  88. Gradle Enterprise

    View full-size slide

  89. Gradle Doctor

    View full-size slide

  90. 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/

    View full-size slide

  91. android-gradle-cache-fix Plugin

    View full-size slide

  92. 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

    View full-size slide

  93. Benchmark your builds

    View full-size slide

  94. Gradle Profiler

    View full-size slide

  95. 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

    View full-size slide

  96. Gradle Profiler

    View full-size slide

  97. Keep your project up-to-date
    • Stay up to date with libraries, plugins, languages

    • Helps pick up performance improvements, cache miss
    fi
    xes, etc

    View full-size slide

  98. Make your build easier to
    work with

    View full-size slide

  99. Android relies on Android Gradle
    Plugin and Gradle to build our
    projects

    View full-size slide

  100. Gradle provides infrastructure
    and plugins provide functionality

    View full-size slide

  101. There’s very little magic

    View full-size slide

  102. To speed up our builds, we can
    use faster hardware, do less
    intensive work, or do less work.

    View full-size slide

  103. Tools such as buildscans and
    Gradle Enterprise help diagnose
    build issues

    View full-size slide

  104. We can optimize our builds
    through caching, modularization,
    and other build acceleration
    strategies

    View full-size slide

  105. By monitoring and profiling
    performance, we may maintain
    efficiency over time

    View full-size slide

  106. Develop a culture of continued
    investment into developer
    productivity for happier, more
    productive, teams.

    View full-size slide

  107. Thank You
    @n8ebel

    goobar.dev

    View full-size slide