Build time optimization
Agent skills for profiling and optimizing mobile app performance (startup, memory, frame-rate, network).
npx -y skills add almasumdev/awesome-mobile-performance-agent-skills --skill build-time-optimizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Cut local and CI build times on Android (Gradle config cache, build cache, KSP over KAPT) and iOS (Xcode build cache, ccache, modules). Use when clean builds exceed ten minutes.
SKILL.md
6.2 KB, as published. Nobody here has run it
Build Time Optimization
Instructions
Slow builds kill iteration. On mobile, a 10-minute CI cycle becomes 40 minutes when flakes retry. This skill covers the high-impact settings for Android (Gradle) and iOS (Xcode) plus Flutter and React Native.
1. Measure First
Android:
./gradlew assembleDebug --scan
Publish the build scan — it highlights longest tasks, non-cacheable steps, configuration time, and up-to-date hit rates. Without the data, tweaking Gradle is guessing.
Xcode: Product → Perform Action → Build with Timing Summary. Or:
xcodebuild -project App.xcodeproj -scheme App -showBuildTimingSummary clean build
Look at the largest Compile/CompileSwift/Ld times.
2. Android — Gradle Configuration Cache
gradle.properties:
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -Dfile.encoding=UTF-8
kotlin.incremental.useClasspathSnapshot=true
android.enableR8.fullMode=true
The configuration cache alone typically halves incremental configuration time. It is strict — kill code that reads System env at configuration time or uses deprecated Groovy closures.
3. Android — KSP over KAPT
KAPT stubs Java for annotation processing and is the #1 hot spot after build tools. Migrate to KSP where available (Room, Dagger/Hilt, Moshi).
plugins {
id("com.google.devtools.ksp") version "2.0.0-1.0.21"
}
dependencies {
ksp("com.google.dagger:hilt-compiler:2.51")
ksp("androidx.room:room-compiler:2.6.1")
}
Typical win: 30–50% faster annotation processing, 2–4× faster incremental.
4. Android — Modularization
Gradle caches per-module. A 50-module project rebuilds only dirty modules. Rules:
- Feature modules should not depend on each other; they depend on a thin
:coreand on interfaces exposed by:data. - Avoid
apidependencies on leaf modules; useimplementationso changes do not ripple. - Use Version Catalogs (
libs.versions.toml) — faster evaluation, single source of truth.
5. Android — Build Cache (Remote)
For team and CI, share the build cache:
# gradle.properties
org.gradle.caching=true
// settings.gradle.kts
buildCache {
local { isEnabled = true }
remote<HttpBuildCache> {
url = uri("https://cache.ci.example.com/cache/")
isPush = System.getenv("CI") == "true"
credentials {
username = System.getenv("BUILD_CACHE_USER")
password = System.getenv("BUILD_CACHE_PASS")
}
}
}
Remote cache hit rates above 70% turn CI times into seconds.
6. iOS — Xcode Tuning
- Enable Build Timing Summary persistently: Defaults write
ShowBuildOperationDurationto YES. - New Build System is the default on modern Xcode; ensure no legacy settings linger.
- Turn on User Script Sandboxing only for scripts that comply; otherwise it disables parallelism.
- Avoid
find . -namescripts in build phases — they disable remote caching.
Module discipline for Swift:
- Prefer static frameworks over dynamic for first-party code — faster link.
- Keep modules small;
importof a 50k-LOC module is expensive. - Use
@_spi/ internal boundaries to reduce public surface that recompiles consumers. - Avoid default protocol witness synthesis in hot code paths; explicit implementations compile faster.
7. iOS — ccache for Objective-C/C/C++
If your project has substantial ObjC/C++ (e.g., CocoaPods with C++ pods, Flutter plugins):
brew install ccache
ln -sf $(brew --prefix)/bin/ccache /usr/local/bin/clang
ln -sf $(brew --prefix)/bin/ccache /usr/local/bin/clang++
Typical win: 30–60% faster on hot rebuilds.
For Swift, ccache does not help. Use Xcode's built-in incremental compiler and avoid forced clean builds.
8. iOS — CocoaPods & SPM
- Prefer Swift Package Manager over CocoaPods where possible — SPM is faster and cache-friendly.
- If stuck on Pods, enable
use_modular_headers!andCOCOAPODS_PARALLEL_CODE_SIGN. - Pre-build binary
.xcframeworkfor big third-party libs; ship as SPM binary target.
9. Flutter
flutter build apk --split-per-abibuilds only the requested ABI.- Commit
.dart_tool/package_config.json? No — but do commitpubspec.lock. - Turn on Gradle config cache just like a native Android project (above). Flutter passes it through.
- Use
pub getwith a private mirror for CI ifpub.devis a bottleneck.
10. React Native
- Metro cache: ensure CI restores
node_modules/.cache/metro. - Hermes bytecode cache on CI via
hermescprecompilation for release. - Yarn / pnpm with workspace-aware cache. pnpm's content-addressable store is very CI-friendly.
- EAS Build cache or Turborepo for monorepos — cache-key on package hashes.
11. CI Caches
Cache on key = lockfile hash:
- uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
iOS Derived Data:
- uses: actions/cache@v4
with:
path: ~/Library/Developer/Xcode/DerivedData
key: xcode-${{ hashFiles('**/Package.resolved','**/Podfile.lock') }}
12. Track Regressions
Every PR should record build time for a cold and a warm build on a stable runner. Fail if median builds regress > 15%.
Checklist
- Gradle config cache + build cache enabled and working (no warnings).
- KAPT replaced with KSP where the processor supports it.
- Project modularized; feature modules do not depend on each other.
- Remote build cache in use on CI with ≥ 70% hit rate.
- Xcode build timing summary reviewed; long tasks addressed.
- SPM used instead of Pods when possible;
use_modular_headers!otherwise. - ccache configured for ObjC/C++ sources.
- CI caches keyed on lockfile hashes.
- Build time tracked per PR; regression threshold enforced.