DOC:00
DOC:00
Back_to_Blogs

Performance Benchmark: React Native vs. Flutter Mobile App

2025.06.308 minPerformanceFlutterReact NativeMobileAndroidiOS
IMG:01
IMG:01
Performance Benchmark: React Native vs. Flutter Mobile App
TXT:02
TXT:02

Co-authored with Muhammad Rijalul Kahfi, Dyva Pandhu, Muhammad Widodo, and Johan Sutrisno at Zero One Group. Originally published on Zero One Group Blog.

The mobile development landscape keeps shifting. React Native recently rolled out a new architecture — Fabric, JSI, and TurboModules — promising significantly better runtime performance. Flutter, meanwhile, has long positioned itself on the strength of its ahead-of-time compiled Dart code and single-threaded rendering pipeline.

We wanted to find out: with the new architecture enabled, how does React Native actually stack up against Flutter in practice?

Background

React Native's legacy architecture had a well-known bottleneck: the asynchronous JavaScript bridge. Every JS-to-native call crossed that bridge, adding latency that compounded under load. The new architecture eliminates the bridge entirely — JSI enables synchronous JS-to-native calls, TurboModules enable lazy native module loading, and Fabric brings a new concurrent rendering system.

Flutter never had this problem. Its rendering pipeline runs entirely in Dart, compiled ahead-of-time, with no runtime JS engine involved. The question is whether React Native's architectural improvements are enough to close the gap.

Objective

We set out to compare both frameworks under controlled, real-world-like conditions across three performance dimensions:

  • CPU utilization — how hard the processor works during typical app operations
  • Memory consumption — how much RAM the app allocates and retains
  • Frame rate (FPS) — smoothness of the UI under load
  • App startup time and bundle size — cold start performance and binary footprint

All tests ran on both Android and iOS to account for platform-specific optimizations.

Metrics Tracked

We tracked the following for each scenario:

  • CPU usage (%)
  • Allocated memory (MB)
  • Frames per second (FPS)
  • Cold start time (ms)
  • APK / IPA size (MB)

Implementation Methodology

App Specification

We built equivalent apps in both React Native and Flutter — same UX, same feature complexity, same interaction patterns. This was critical to ensure we were measuring the framework, not implementation differences.

Test Scenarios

Three scenarios were benchmarked:

  1. App Start — cold start from killed state to first interactive frame
  2. Resource-intensive Task — heavy computation combined with UI rendering
  3. Input Responsiveness — rapid user interactions (taps, drags) measured for UI thread responsiveness

Profiling Tools

  • Android: Android Profiler (CPU, memory), Perfetto (startup traces)
  • iOS: Xcode Instruments (CPU, memory, FPS), MetricKit (startup time)

Test Environment

Details
Android deviceSamsung Galaxy A14
iOS deviceiPhone 8
Host machineMacBook Air M1 2020, 8 GB RAM
React NativeNew architecture enabled (Fabric + JSI + TurboModules)
Build modeRelease (both platforms)

Manual Testing Approach

Despite wanting full automation, we ran into significant limitations with automated profiling tools in release mode. Detox and integration_test introduce their own performance overhead that skews CPU and memory readings. Maestro doesn't support iOS physical devices in release mode. Appium's automation latency makes frame-rate measurements unreliable.

Warning

Automated benchmarking tools often instrument the app in ways that inflate CPU and memory readings. We opted for manual testing with physical devices in release mode to get numbers that reflect actual user-facing performance.

We used physical devices, ran each scenario multiple times, and averaged the results to reduce noise.

Benchmark Results

App Size & Startup Time

On Android, Flutter's APK is significantly smaller than React Native's (19 MB vs 76 MB). Flutter also has a faster cold start on iOS (771.8 ms vs 953.4 ms).

On Android cold start, the picture flips: React Native launches in 593 ms vs Flutter's 1,738 ms — likely due to Flutter's engine initialization overhead. On iOS, React Native's IPA is also slightly smaller (7.3 MB vs 10.5 MB).

MetricFlutterReact Native
APK size (Android)19 MB76 MB
IPA size (iOS)10.5 MB7.3 MB
Cold start — Android1,738 ms593 ms
Cold start — iOS771.8 ms953.4 ms

APK size comparison — Flutter vs React Native on AndroidAPK size comparison — Flutter vs React Native on Android

IPA size comparison — Flutter vs React Native on iOSIPA size comparison — Flutter vs React Native on iOS

Android cold start time comparisonAndroid cold start time comparison

iOS cold start time comparisoniOS cold start time comparison

Architect's_Note

Bundle size differences matter in real-world distribution. A smaller APK means faster downloads, particularly on slower mobile networks — relevant for Southeast Asian markets where a large share of users are on 4G or below.

Scenario 1: Idle / Initial View

Under minimal load (initial render, no active computation), Flutter had lower CPU usage on Android (4–8% vs 15–22% for RN). On iOS the gap was stark — React Native's CPU spiked to 90–222% (multi-core), while Flutter stayed at 21–34%. Memory consumption was higher for React Native on Android; iOS was comparable. FPS results varied by platform, with Android's higher reported rates reflecting the profiler counting all refresh events on a 120 Hz display.

MetricPlatformFlutterReact Native
CPUAndroid4–8%15–22%
CPUiOS21–34%90–222%
MemoryAndroid47–152 MB170–223 MB
MemoryiOS49–54 MB68–78 MB
FPSAndroid3272–132
FPSiOS5631

Scenario 1 — Android CPU utilizationScenario 1 — Android CPU utilization

Scenario 1 — Android total memoryScenario 1 — Android total memory

Scenario 1 — Android allocated memoryScenario 1 — Android allocated memory

Scenario 1 — iOS CPU utilizationScenario 1 — iOS CPU utilization

Scenario 1 — iOS total memoryScenario 1 — iOS total memory

Scenario 1 — iOS FPSScenario 1 — iOS FPS

Scenario 2: Resource-Intensive Task

This is where the gap widened. Under sustained heavy computation combined with active UI rendering, Flutter held lower CPU across both platforms. On iOS, React Native's CPU hit 95–300% (multi-core) vs Flutter's 49–54%. Memory was higher in React Native on Android (223–243 MB vs 178 MB); on iOS both were similar. Flutter held a more stable FPS on iOS (54.2 vs 32).

MetricPlatformFlutterReact Native
CPUAndroid7–11%17–29%
CPUiOS49–54%95–300%
MemoryAndroid178 MB223–243 MB
MemoryiOS52–53 MB52–57 MB
FPSAndroid54105–133
FPSiOS54.232

Scenario 2 — Android CPU utilizationScenario 2 — Android CPU utilization

Scenario 2 — Android total memoryScenario 2 — Android total memory

Scenario 2 — Android allocated memoryScenario 2 — Android allocated memory

Scenario 2 — iOS CPU utilizationScenario 2 — iOS CPU utilization

Scenario 2 — iOS total memoryScenario 2 — iOS total memory

Scenario 2 — iOS FPSScenario 2 — iOS FPS

Scenario 3: Input Responsiveness

Under rapid input interaction (continuous taps and drags), React Native's CPU spiked more aggressively — 15–32% on Android and 65–230% on iOS vs Flutter's 8–12% and 24–55% respectively. Flutter's input handling stayed relatively flat, consistent with its single-threaded rendering model that avoids JS-thread contention. FPS was comparable on iOS; Android reported higher values for RN again due to profiler behavior on high-refresh displays.

MetricPlatformFlutterReact Native
CPUAndroid8–12%15–32%
CPUiOS24–55%65–230%
MemoryAndroid169–174 MB122 MB
MemoryiOS52–53 MB52–61 MB
FPSAndroid52–57111–132
FPSiOS55.551

Scenario 3 — Android CPU utilizationScenario 3 — Android CPU utilization

Scenario 3 — Android total memoryScenario 3 — Android total memory

Scenario 3 — Android allocated memoryScenario 3 — Android allocated memory

Scenario 3 — iOS CPU utilizationScenario 3 — iOS CPU utilization

Scenario 3 — iOS total memoryScenario 3 — iOS total memory

Scenario 3 — iOS FPSScenario 3 — iOS FPS

Automation Challenges

It's worth being transparent about the limits of this benchmark:

  • Framework overhead: Many testing frameworks introduce their own CPU/memory overhead, making release-mode measurements unreliable
  • Timing inconsistencies: Automated inputs (taps, drags) exhibit variable execution timing, which skews latency-sensitive measurements
  • Cross-platform parity: Designing identical automation flows for both Flutter and React Native — on both Android and iOS — without introducing framework-specific bias is non-trivial

These constraints reinforced our decision to benchmark manually on physical devices.

Conclusion

Across all three scenarios, Flutter demonstrated more efficient CPU and memory utilization, particularly under resource-intensive workloads. React Native's new architecture is a meaningful improvement over the legacy bridge model, but it still carries the overhead of a JavaScript engine — which shows up under load.

On startup and bundle size, the results split by platform. Flutter wins on Android (smaller APK, faster cold start). React Native has a slight edge on iOS.

Pro_Tip

If your primary concern is runtime performance — especially for animation-heavy or computation-heavy screens — Flutter's ahead-of-time compiled pipeline gives it a structural advantage that the new RN architecture hasn't fully erased. If iOS cold-start or ecosystem/tooling familiarity matters more, React Native's new architecture is a compelling choice.

Short Analysis

React Native's new architecture (Fabric + JSI + TurboModules) reduces JS-to-native communication overhead substantially. But the JS engine itself remains in the critical path for rendering and logic — and that shows under sustained load.

Flutter's rendering pipeline is structurally different: Dart is compiled AOT, the rendering engine (Impeller/Skia) runs on a dedicated thread, and there's no runtime bridge. This gives Flutter a more predictable performance profile, particularly for frame rates.

These findings are consistent with architectural expectations. They're preliminary — single-device benchmarks on specific scenarios — but they're directionally reliable.

Further Direction

This benchmark is a starting point. For more definitive conclusions, we'd want to:

  • Run longer test durations with automated collection to observe performance trends over time
  • Test on a wider range of devices — especially low-end hardware where memory and CPU constraints are more pronounced
  • Measure background state performance (active vs. background vs. terminated)
  • Factor in developer experience: tooling, ecosystem maturity, community support, and hiring pool

One area we deliberately excluded: comparisons with Lynx. While Lynx is sometimes mentioned in cross-platform discussions, it's primarily a document rendering engine — not directly comparable for interactive mobile app development.

Artifacts

The full source code for both the Flutter and React Native benchmark apps is open:

All performance recordings and raw data are available there for reproducibility.

NAV:03
NAV:03

Command Palette

Search for pages and actions