White Screen on App Startup: Causes and Fixes
A white screen on launch is usually 1-3 seconds the app spends loading before showing your splash or content. It is not a crash but feels like one, especially on older devices. Users mistake it for br
A white screen on launch is usually 1-3 seconds the app spends loading before showing your splash or content. It is not a crash but feels like one, especially on older devices. Users mistake it for broken. This guide covers why it happens and how to eliminate it.
What "white screen" actually is
Two distinct phenomena:
- Android splash screen default — when your app launches, the system shows a window with your theme's
android:windowBackgroundwhile your Activity initializes. If background is white, user sees white.
- Delay between native view initialization and content render — your layout inflates, but data / assets not yet loaded.
Perceptual latency is what matters. 500ms white = acceptable. 2 seconds white = broken.
Causes
1. Heavy onCreate / Application.onCreate
Too much work before first frame. SDKs initializing. Database opening. Analytics dispatching.
Fix: Defer non-critical init. Use App Startup library. Measure startup budget ruthlessly.
2. No branded splash theme
Default theme with white windowBackground → user sees white for 300-1000ms.
Fix: Theme has colored / branded windowBackground or uses SplashScreen API (Android 12+).
3. React Native / Flutter hot reload in dev
Metro bundler / Flutter reload takes seconds in dev; release bundles are instant. New devs think it is a bug.
Fix: Dev-only; ignore in release.
4. Network-at-launch
Splash shows for 3 seconds while fetching remote config. On poor network, splash lingers.
Fix: Cached config displayed immediately; refresh in background.
5. Large initial bundle
App downloads config / assets / content on first launch. Slow network → long wait.
Fix: Ship minimum viable bundle. Download extras after first interactive render.
6. First-run vs warm start confusion
Cold start: process not running. Takes longest. Warm start: activity was killed but process alive. Hot start: both alive.
Cold start on a 2019 phone running Android 9 with 3GB RAM can be 2-5 seconds for a heavy app. Budget appropriately.
Targets (2026)
| Class | Cold | Warm | Hot |
|---|---|---|---|
| 2023 flagship | < 500ms | < 150ms | < 50ms |
| 2023 mid | < 800ms | < 250ms | < 100ms |
| 2020 budget | < 1500ms | < 500ms | < 200ms |
| 2018 low-end | < 2500ms | < 800ms | < 300ms |
Anything over 2 seconds cold on mid-tier is noticeable.
Fix patterns
Use the SplashScreen API (Android 12+)
<style name="AppTheme.Splash" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/brand</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/logo</item>
<item name="postSplashScreenTheme">@style/AppTheme</item>
</style>
Baseline profiles (Android 9+)
Profile-guided compilation for hot paths. Measured 20-30% cold start improvement.
Lazy init via App Startup library
class CrashlyticsInitializer : Initializer<FirebaseCrashlytics> {
override fun create(context: Context): FirebaseCrashlytics = FirebaseCrashlytics.getInstance()
override fun dependencies(): List<Class<out Initializer<*>>> = listOf(FirebaseAppInitializer::class.java)
}
Defer the non-critical
Analytics, ad SDKs, remote config fetch, background sync — all after first frame.
Show something immediately
Static splash image at frame 1. Never a blank canvas.
Measurement
adb shell am start -W com.example/.MainActivity
# TotalTime: 842
Run 5 times. Median. Compare across releases.
Jetpack Macrobenchmark
@Test fun startup() = rule.measureRepeated(
packageName = "com.example",
metrics = listOf(StartupTimingMetric()),
iterations = 5,
startupMode = StartupMode.COLD,
) { pressHome(); startActivityAndWait() }
Stable numbers for CI regression.
How SUSA measures
SUSA's impatient persona abandons slow-launching apps. If cold start exceeds threshold (default 3s), it is flagged as an issue. Performance monitor captures CPU/memory/frame-time during startup window.
susatest-agent test myapp.apk --persona impatient --steps 20
Common mistakes
- Debug-build testing only (release is different with ProGuard)
- Flagship-device testing only (users have budget phones)
- Dev-mode startup with hot reload (release is faster)
- Measuring warm start and shipping cold-start regression
White screen on startup is solvable. 500ms cold start on mid-tier is achievable in most apps with one focused sprint.
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