跳到主要内容
知仓学习社ZHICANG

gradle-build-performance

Debug and optimize Android/Gradle build performance. Use when builds are slow, investigating CI/CD performance, analyzing build scans, or identifyin…

不碰外部(只输出文字)无严重或高危命中new-silvermoon/awesome-android-agent-skills

它会碰到什么

扫了多少1 个文本文件,8 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Gradle Build Performance

When to Use

  • Build times are slow (clean or incremental)
  • Investigating build performance regressions
  • Analyzing Gradle Build Scans
  • Identifying configuration vs execution bottlenecks
  • Optimizing CI/CD build times
  • Enabling Gradle Configuration Cache
  • Reducing unnecessary recompilation
  • Debugging kapt/KSP annotation processing

Example Prompts

  • "My builds are slow, how can I speed them up?"
  • "How do I analyze a Gradle build scan?"
  • "Why is configuration taking so long?"
  • "Why does my project always recompile everything?"
  • "How do I enable configuration cache?"
  • "Why is kapt so slow?"

Workflow

  1. Measure Baseline — Clean build + incremental build times
  2. Generate Build Scan./gradlew assembleDebug --scan
  3. Identify Phase — Configuration? Execution? Dependency resolution?
  4. Apply ONE optimization — Don't batch changes
  5. Measure Improvement — Compare against baseline
  6. Verify in Build Scan — Visual confirmation

Quick Diagnostics

Generate Build Scan

./gradlew assembleDebug --scan

Profile Build Locally

./gradlew assembleDebug --profile
# Opens report in build/reports/profile/

Build Timing Summary

./gradlew assembleDebug --info | grep -E "^\:.*"
# Or view in Android Studio: Build > Analyze APK Build

Build Phases

| Phase | What Happens | Common Issues |

|-------|--------------|---------------|

| Initialization | settings.gradle.kts evaluated | Too many include() statements |

| Configuration | All build.gradle.kts files evaluated | Expensive plugins, eager task creation |

| Execution | Tasks run based on inputs/outputs | Cache misses, non-incremental tasks |

Identify the Bottleneck

Build scan → Performance → Build timeline
  • Long configuration phase: Focus on plugin and buildscript optimization
  • Long execution phase: Focus on task caching and parallelization
  • Dependency resolution slow: Focus on repository configuration

12 Optimization Patterns

1. Enable Configuration Cache

Caches configuration phase across builds (AGP 8.0+):

# gradle.properties
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn

2. Enable Build Cache

Reuses task outputs across builds and machines:

# gradle.properties
org.gradle.caching=true

3. Enable Parallel Execution

Build independent modules simultaneously:

# gradle.properties
org.gradle.parallel=true

4. Increase JVM Heap

Allocate more memory for large projects:

# gradle.properties
org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC

5. Use Non-Transitive R Classes

Reduces R class size and compilation (AGP 8.0+ default):

# gradle.properties
android.nonTransitiveRClass=true

6. Migrate kapt to KSP

KSP is 2x faster than kapt for Kotlin:

// Before (slow)
kapt("com.google.dagger:hilt-compiler:2.51.1")

// After (fast)
ksp("com.google.dagger:hilt-compiler:2.51.1")

7. Avoid Dynamic Dependencies

Pin dependency versions:

// BAD: Forces resolution every build
implementation("com.example:lib:+")
implementation("com.example:lib:1.0.+")

// GOOD: Fixed version
implementation("com.example:lib:1.2.3")

8. Optimize Repository Order

Put most-used repositories first:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()      // First: Android dependencies
        mavenCentral() // Second: Most libraries
        // Third-party repos last
    }
}

9. Use includeBuild for Local Modules

Composite builds are faster than project() for large monorepos:

// settings.gradle.kts
includeBuild("shared-library") {
    dependencySubstitution {
        substitute(module("com.example:shared")).using(project(":"))
    }
}

10. Enable Incremental Annotation Processing

# gradle.properties
kapt.incremental.apt=true
kapt.use.worker.api=true

11. Avoid Configuration-Time I/O

Don't read files or make network calls during configuration:

// BAD: Runs during configuration
val version = file("version.txt").readText()

// GOOD: Defer to execution
val version = providers.fileContents(file("version.txt")).asText

12. Use Lazy Task Configuration

Avoid create(), use register():

// BAD: Eagerly configured
tasks.create("myTask") { ... }

// GOOD: Lazily configured
tasks.register("myTask") { ... }

Common Bottleneck Analysis

Slow Configuration Phase

Symptoms: Build scan shows long "Configuring build" time

Causes & Fixes:

| Cause | Fix |

|-------|-----|

| Eager task creation | Use tasks.register() instead of tasks.create() |

| buildSrc with many dependencies | Migrate to Convention Plugins with includeBuild |

| File I/O in build scripts | Use providers.fileContents() |

| Network calls in plugins | Cache results or use offline mode |

Slow Compilation

Symptoms: :app:compileDebugKotlin takes too long

Causes & Fixes:

| Cause | Fix |

|-------|-----|

| Non-incremental changes | Avoid build.gradle.kts changes that invalidate cache |

| Large modules | Break into smaller feature modules |

| Excessive kapt usage | Migrate to KSP |

| Kotlin compiler memory | Increase kotlin.daemon.jvmargs |

Cache Misses

Symptoms: Tasks always rerun despite no changes

Causes & Fixes:

| Cause | Fix |

|-------|-----|

| Unstable task inputs | Use @PathSensitive, @NormalizeLineEndings |

| Absolute paths in outputs | Use relative paths |

| Missing @CacheableTask | Add annotation to custom tasks |

| Different JDK versions | Standardize JDK across environments |


CI/CD Optimizations

Remote Build Cache

// settings.gradle.kts
buildCache {
    local { isEnabled = true }
    remote<HttpBuildCache> {
        url = uri("https://cache.example.com/")
        isPush = System.getenv("CI") == "true"
        credentials {
            username = System.getenv("CACHE_USER")
            password = System.getenv("CACHE_PASS")
        }
    }
}

Gradle Enterprise / Develocity

For advanced build analytics:

// settings.gradle.kts
plugins {
    id("com.gradle.develocity") version "3.17"
}

develocity {
    buildScan {
        termsOfUseUrl.set("https://gradle.com/help/legal-terms-of-use")
        termsOfUseAgree.set("yes")
        publishing.onlyIf { System.getenv("CI") != null }
    }
}

Skip Unnecessary Tasks in CI

# Skip tests for UI-only changes
./gradlew assembleDebug -x test -x lint

# Only run affected module tests
./gradlew :feature:login:test

Android Studio Settings

File → Settings → Build → Gradle

  • Gradle JDK: Match your project's JDK
  • Build and run using: Gradle (not IntelliJ)
  • Run tests using: Gradle

File → Settings → Build → Compiler

  • Compile independent modules in parallel: ✅ Enabled
  • Configure on demand: ❌ Disabled (deprecated)

Verification Checklist

After optimizations, verify:

  • [ ] Configuration cache enabled and working
  • [ ] Build cache hit rate > 80% (check build scan)
  • [ ] No dynamic dependency versions
  • [ ] KSP used instead of kapt where possible
  • [ ] Parallel execution enabled
  • [ ] JVM memory tuned appropriately
  • [ ] CI remote cache configured
  • [ ] No configuration-time I/O

References

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。