DOC:00
DOC:00
Back_to_Blogs

Performance Benchmark: React Native vs. Flutter Mobile App

2025.06.308 minFlutterReact NativeMobilePerformanceAndroidiOS
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)

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. Flutter also edges out React Native on cold start time for Android.

On iOS, the picture flips: React Native's IPA is slightly smaller, and cold start is marginally faster — likely a result of the new architecture's optimizations on the Apple platform.

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), both frameworks performed similarly. CPU usage was low for both, FPS stayed near 60, and memory footprints were comparable.

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. During sustained heavy computation combined with active UI rendering:

  • Android CPU: React Native peaked around 86%, Flutter around 81%
  • Android Memory: React Native allocated ~11.97 MB, Flutter ~11.41 MB
  • FPS: Flutter maintained more stable frame rates; React Native showed more frame drops under peak load

iOS results followed a similar pattern — Flutter maintained more consistent resource usage across the duration of the task.

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 utilization spiked more aggressively than Flutter's. Flutter's input handling stayed relatively flat, consistent with its single-threaded rendering model that avoids JS-thread contention.

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