How We Cut React Native Startup Time from 3.8s to 1.5s
The levers that cut React Native startup time by about 60%: measuring cold start properly, Hermes, image optimisation and cache-first fetching.
Full-Stack, Mobile & AI Engineer
A user taps your icon and waits. At 3.8 seconds the app finally shows something useful, and some of those users have already switched to something else. Startup time is the first impression of every session, and it's measured by stopwatch, not by how elegant the code is.
Across eight apps I migrated to React Native's New Architecture, we cut load time by about 60%, from 3.8 seconds to 1.5, through three levers: Hermes, image optimisation and cache-first fetching. This article explains how to measure React Native startup time honestly, what each of those levers does, and the other changes that usually matter, so you can find your own 60%.
Key takeaways
- Measure cold start on a mid-range Android phone with a release build. Simulators and debug builds tell you very little.
- Hermes compiles JavaScript to bytecode ahead of time, so less work happens on launch. It's the default engine, and Hermes V1 has been the default since React Native 0.84.
- Images are a hidden startup cost: oversized files, no caching and decoding on the main path all delay the first useful screen.
- Cache-first fetching shows the last known data instantly and refreshes in the background, instead of waiting on the network before rendering.
- Do less before the first frame: defer analytics, remote config and non-critical requests until after the first screen appears.
Step 0: measure the right thing
"Startup time" means different things, so define it before optimising:
| Metric | What it measures |
|---|---|
| Cold start | App launched from scratch, process not in memory |
| Warm start | Process alive, activity or screen recreated |
| Time to first frame | First pixels drawn (often the splash screen) |
| Time to interactive | The first real screen is usable with data |
The number users feel is cold start to interactive. Measure it on a release build, on a mid-range Android device (where the gap is biggest), several times, and take the median.
Tools that help:
- React Native DevTools for JavaScript profiling.
- Android Studio profiler and Perfetto, and Xcode Instruments' App Launch template, for native startup.
- Performance marks in your code (
performance.now()at key moments) logged in release builds. - Production metrics: Android vitals in Play Console treats cold starts of 5 seconds or more as excessive, and Expo's EAS Observe reports cold and warm launch, time to render and time to interactive from real devices.
Lever 1: Hermes and less JavaScript work at launch
Hermes compiles your JavaScript into bytecode when you build the app, so the device doesn't parse and compile it at runtime. React Native has defaulted to Hermes for years, and Hermes V1 became the default engine in React Native 0.84.
Being on Hermes is the start, not the end. What matters is how much JavaScript runs before your first screen:
- Inline requires (a Metro option, enabled in React Native's default Metro config) delay loading modules until they're actually used.
- Avoid heavy work at module scope, such as building large lookup tables, initialising SDKs or parsing big JSON files when files are imported.
- Trim dependencies. Large date, utility or charting libraries imported on the first screen add parse and execution time.
- Lazy-load screens that aren't needed at launch.
With the New Architecture, native modules are also initialised lazily as TurboModules when first used, rather than all at startup, which removes work you never asked for.
Lever 2: images
Images are easy to overlook because they "load asynchronously". But the first screen often waits for a hero image, a logo or a list of thumbnails, and oversized images cost network time, memory and decode time.
- Serve the right size. Don't send a 3000-pixel photo to a 400-pixel slot. Resize on the server or through an image CDN.
- Use modern formats such as WebP or AVIF where supported.
- Use a caching image component like
expo-image, with disk and memory caching, and placeholders (for example a blurhash) so layout is stable. - Prefetch images for the first screen during the splash, and don't block rendering on them.
- Bundle the few images needed at launch (logo, empty states) instead of fetching them.
Lever 3: cache-first fetching
The slowest startup pattern is: open app, show spinner, wait for the network, then render. On a train or a weak signal, that's seconds.
Cache-first flips it:
- On launch, render immediately from the last cached data.
- Fetch fresh data in the background.
- Update the screen when it arrives, without a jarring reload.
With TanStack Query, persist the query cache to fast local storage (MMKV is a common choice) and restore it at startup. Users see their dashboard, workouts or bookings instantly, and the app quietly refreshes. This is the same approach behind offline-first apps, applied to startup.
From the field: These three levers come straight from my own work: migrating eight apps to the New Architecture and cutting load time by about 60% (3.8 seconds to 1.5) through Hermes, image optimisation and cache-first fetching, while holding stable 60fps animation. None of it required leaving React Native.
Other changes that usually help
| Symptom | Likely cause | Fix |
|---|---|---|
| Long splash screen | Waiting for fonts, auth, remote config in sequence | Load in parallel; keep the splash only for essentials |
| Spinner after the splash | Network-first first screen | Cache-first rendering |
| Slow only on Android | Low-end CPU, big JS bundle, large images | Profile on a mid-range device; trim and resize |
| Startup got slower over months | SDKs initialised at launch | Defer analytics and non-critical SDKs until after first frame |
| Janky first scroll | Heavy list items, unoptimised images | FlashList, smaller images, memoised rows |
Keep the splash screen visible only until the essentials are ready (SplashScreen.preventAutoHideAsync() and hideAsync() in Expo), and render the first real screen as soon as you can, even if some data is still loading.
FAQ
What is a good startup time for a React Native app?
Aim for well under two seconds to a usable screen on a mid-range Android phone with a release build. Google's Android vitals treats cold starts of five seconds or more as excessive. Users notice anything that feels slower than the apps they use every day.
Does Hermes make React Native apps start faster?
Yes. Hermes compiles JavaScript to bytecode at build time, which reduces work on launch, and it's the default engine; Hermes V1 has been the default since React Native 0.84. The remaining gains come from running less JavaScript before the first screen.
How do I measure React Native startup time?
Measure cold start to interactive on a release build on a real mid-range device, several times, and use the median. Combine native profilers (Android Studio, Perfetto, Xcode Instruments), performance marks in your code, and production metrics such as Android vitals or EAS Observe.
Does the New Architecture improve startup time?
It can. TurboModules are initialised lazily when first used, instead of all at launch, and JSI removes bridge overhead. The biggest improvements still come from doing less work before the first screen: lighter JavaScript, smaller images and cache-first data.
Next steps
If your app takes more than a couple of seconds to become usable, I can profile it on real devices and give you a prioritised list of fixes, usually with the biggest wins in the first week. Get in touch, or see how I work as a React Native developer.
Sources
- Using Hermes, React Native docs
- React Native 0.84: Hermes V1 by default, React Native blog
- App startup time (Android vitals), Android Developers
- Image (expo-image), Expo
- persistQueryClient, TanStack Query
- SplashScreen, Expo
Related
React Native Performance in 2026: The Checklist That Matters
A practical React Native performance optimization checklist for 2026: measuring, startup, re-renders, lists, images, animations, memory and monitoring.
Migrating to the New Architecture: A Field Guide from 8 Migrations
A step-by-step guide to migrating a React Native app to the New Architecture in 2026: auditing libraries, the 0.81 path, common breakages and testing.
Hermes in 2026: What It Does and How to Profile with It
What Hermes does for React Native in 2026, what changed with Hermes V1, Hermes vs JavaScriptCore, and how to profile CPU and memory with DevTools.
