Apple's watchdog process kills any app that doesn't become interactive within 20 seconds of launch. Google Play triggers an ANR (Application Not Responding) rejection when the main thread blocks for more than 5 seconds. Synchronous I/O in module initialization, blocking API calls before the first render, or missing SplashScreen.hideAsync() calls all cause the app to appear frozen — ISO 25010:2011 time-behaviour failure. A slow launch doesn't just risk rejection; it trains reviewers to view the app as low quality, increasing scrutiny of everything else.
High because exceeding Apple's 20-second watchdog threshold causes an automatic process kill and rejection, reproducible on any network-constrained device.
Move all async startup work behind the splash screen and defer it past first render.
// app/_layout.tsx (Expo Router)
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
const [ready, setReady] = useState(false);
useEffect(() => {
async function prepare() {
try {
await Font.loadAsync({ 'MyFont': require('./assets/MyFont.ttf') });
} finally {
setReady(true);
await SplashScreen.hideAsync();
}
}
prepare();
}, []);
if (!ready) return null;
return <Slot />;
}
Add a 10-second AbortController timeout to any API call that runs during startup. Test on a low-end device or throttled simulator, not a flagship.
app-store-review-blockers.completeness-stability.launch-performancehighuseEffect with no loading state (app appears frozen until data loads); setTimeout or setInterval calls at startup that delay rendering; heavy image loading without lazy/progressive strategies; use of expo-font or expo-asset without SplashScreen.preventAutoHideAsync() + SplashScreen.hideAsync() (causing either a flash of unstyled content or an extended black screen). For Android, look for Application.onCreate() doing heavy work. For iOS, look for application(_:didFinishLaunchingWithOptions:) doing synchronous I/O. Also check app.json for any explicit delay in the splash screen config."Root component fetches user profile synchronously before first render — app will appear frozen on slow networks" or "SplashScreen.hideAsync() never called — splash screen may persist indefinitely"useEffect hooks with loading statesawait SplashScreen.preventAutoHideAsync();
await Font.loadAsync({ ... });
await SplashScreen.hideAsync();