Slow App Startup: Root Causes and Fixes (2026 Guide)
App startup is the first impression and a strong abandonment driver. Google's research shows a 2-second cold start is the practical ceiling before abandonment climbs sharply. This guide covers how to
App startup is the first impression and a strong abandonment driver. Google's research shows a 2-second cold start is the practical ceiling before abandonment climbs sharply. This guide covers how to measure startup, the common causes of slowness, and fixes that actually move the number.
Types of startup
- Cold start — app process not running; fresh JVM/runtime, no cached state
- Warm start — process alive, activity destroyed; app returns to front
- Hot start — process and activity alive; app foregrounded from background
Cold is the hard one and the one you should benchmark.
How to measure
Android
adb shell am start -W com.example/.MainActivity
# TotalTime: 842
TotalTime is the time from launch intent to first drawn frame. Benchmark on a real mid-tier device (not emulator, not flagship). Aim:
- Cold start < 500ms on mid-tier 2023 device
- Cold start < 1s on low-tier 2019 device
iOS
Pre-main latency + main thread until first frame. Xcode: Product → Profile → Time Profiler / App Launch template.
Jetpack Macrobenchmark (Android)
@Test
fun startup() = benchmarkRule.measureRepeated(
packageName = "com.example",
metrics = listOf(StartupTimingMetric()),
iterations = 5,
startupMode = StartupMode.COLD,
) {
pressHome()
startActivityAndWait()
}
Gives you median, 90th percentile, with stable numbers in CI.
Common causes
1. Heavy Application.onCreate
The most common. SDKs initialized synchronously: Firebase, Crashlytics, Segment, Amplitude, Mixpanel, Adjust, Branch. Each takes 50-200ms. Ten SDKs → 1-2 seconds.
Fix: App Startup library (Android Jetpack). Declare initializers with dependencies, lazy-init anything not needed for first frame.
class CrashlyticsInitializer : Initializer<FirebaseCrashlytics> {
override fun create(context: Context): FirebaseCrashlytics = FirebaseCrashlytics.getInstance()
override fun dependencies(): List<Class<out Initializer<*>>> = listOf(FirebaseInitializer::class.java)
}
2. Splash activity doing work
SplashActivity loads config, checks auth, pre-warms caches. All synchronously on UI thread.
Fix: Splash is display only. The work happens in the real first activity, or better, in Dispatchers.IO while the real activity renders.
3. Main activity layout too expensive
Deep view hierarchy, 50+ views, ConstraintLayout with 20 constraints. Inflation + measure + layout + draw takes 200ms on low-end.
Fix:
- Flatten hierarchy (ConstraintLayout > nested LinearLayouts)
- Lazy-inflate via ViewStub for below-the-fold
- Jetpack Compose with deferred composition for complex screens
4. Early database query
Room initialization synchronous; first query runs on main thread.
Fix: Initialize Room from Dispatchers.IO. Use LiveData / Flow so queries are async by default.
5. Early network call
App launches, fetches user profile before showing UI.
Fix: Show UI first, fetch async, update when ready. Stale cache better than blank screen.
6. Image / asset decoding
Large PNG in a launcher icon, decoded on main thread.
Fix: WebP for assets. Decode on background thread via image loading library.
7. Dex / ART compilation on first install
Android's first launch of a new version compiles classes. One-time cost but user-visible.
Fix: Baseline Profiles (Android 9+). Ship profile files that pre-compile hot paths. 20-30% startup improvement typical.
8. Multi-process overhead
App has content providers or services in separate processes. Each needs separate init.
Fix: Audit android:process tags. Merge unless truly separate.
iOS-specific
Pre-main time
Dynamic linker loads all Mach-O images, runtime initializers, +load methods.
Fix:
- Minimize dynamic frameworks (link statically where possible)
- Eliminate +load methods in favor of +initialize
- Check
DYLD_PRINT_STATISTICS=1for per-phase timing
Storyboard heavy
Initial storyboard loads 10 view controllers even though first screen uses one.
Fix: Programmatic init for first screen or split into multiple storyboards.
Benchmark targets by device class
| Device class | Cold start target | Warm start | Hot start |
|---|---|---|---|
| 2023 flagship | < 400ms | < 150ms | < 50ms |
| 2023 mid-tier | < 600ms | < 200ms | < 80ms |
| 2022 budget | < 1000ms | < 350ms | < 150ms |
| 2019 budget | < 1800ms | < 600ms | < 250ms |
Pass all four or the app feels slow to the long tail.
Baseline profiles (Android)
Ship pre-compiled profile files in your APK. They tell ART which classes and methods to pre-compile at install time. Cold start drops 20-30%.
Generate once via Macrobenchmark:
@OptIn(ExperimentalBaselineProfilesApi::class)
@Test fun generate() = baselineProfileRule.collectBaselineProfile("com.example") {
pressHome(); startActivityAndWait()
// Your critical user journey
}
Commit the output to src/main/baseline-prof.txt. Rebuild. Startup faster.
How SUSA measures startup
SUSA records cold start time as part of every exploration. The impatient persona abandons the session if startup exceeds 3 seconds — surfacing when startup regresses. Performance monitor samples CPU, memory, and FPS continuously, so you can see if startup is CPU-bound (decoding, parsing) or I/O-bound (disk reads, network).
Report includes:
- Cold start time (from launch intent to first frame)
- First interactive time (when any UI element accepts a tap)
- Breakdown by phase: pre-main, app creation, activity creation, first draw
susatest-agent test myapp.apk --persona impatient --steps 30
Fixes in order of ROI
- Baseline profiles — 20-30% cold start, zero user-code change
- Defer SDK init — 200-1000ms typically
- Move work off main — 100-500ms
- Flatten UI hierarchy — 50-200ms
- Fewer dynamic frameworks (iOS) — 100-500ms
Startup is a solvable problem. A 3-second cold start can usually reach 1 second in one engineering sprint. Prioritize — it is one of the highest-leverage perf investments you can make.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free