
The cross-platform war didn't end. It just changed battlefields.
For years, mobile teams tolerated embarrassing micro-stutters, white flash screens during rapid scrolling, and frame drops that made users question their hardware. Framework maintainers blamed device fragmentation. Hardware vendors blamed cheap abstraction layers.
Both Flutter and React Native eventually faced an uncomfortable truth: their core engines were structurally flawed.
Flutter relied on Skia, an engine that routinely locked the UI thread to compile GLSL shaders on the fly. React Native routed layout math through an asynchronous, single-threaded JSON bridge that choked the moment you touched a fast scroll view.

Today, those legacy architectures are dead. Flutter dropped Skia on mobile to launch Impeller. React Native killed the Bridge to mandate Fabric, JSI, and Hermes by default.
Marketing sites claim both frameworks completely "solved performance." The telemetry data tells a far more aggressive, cutthroat story.
Flutter’s architectural premise is radical: trust zero platform UI code. Impeller doubles down on this philosophy.

Offline Shader Compilation
Skia dynamically compiled graphics shaders at runtime. When an app triggered a blur, shadow, or clip mask for the first time, the main thread froze while Skia compiled the GLSL script. Impeller forces all shaders through an offline compiler (impellerc) at build time. When your app launches, the GPU pipeline state objects (PSOs) are already warm.
Direct Metal & Vulkan Execution
Impeller bypasses abstraction layers to talk directly to modern graphics APIs. It targets Metal on iOS and Vulkan on Android (falling back to OpenGL ES only on ancient hardware).
The Structural Penalty
You carry an entire rendering engine inside your binary. You own every pixel, but you also pay the baseline RAM tax required to boot that engine context.
React Native abandoned its asynchronous JSON Bridge. The old system serialized UI trees into JSON strings, sent them across a bridge, and deserialized them on the native side. Rapid user gestures destroyed this architecture.

JavaScript Interface (JSI)
JSI replaces stringified JSON calls with direct C++ host object pointers. JavaScript can invoke native C++ methods synchronously—no bridge overhead.
Fabric C++ Renderer
Fabric handles layout in C++ via the Yoga engine. It builds an immutable shadow tree in C++, allowing concurrent layout passes that fully align with React 18 scheduling priorities.
Platform Native Views
Fabric doesn't paint pixels on a canvas. It mounts real UIView instances on iOS and android.view.View instances on Android.
To cut through vendor bias, performance was measured using production release builds across three device tiers:
High-End
iPhone 15 Pro (Apple A17 Pro, ProMotion 120Hz)
Mid-Range
Google Pixel 8a (Tensor G3, 120Hz)
Budget Real-World
Samsung Galaxy A14 (MediaTek Helio G80, 60Hz)
Versions
Flutter 3.27+ (Impeller enabled) vs. React Native 0.76+ (New Architecture, Hermes, Fabric active).

On static screens, both frameworks comfortably lock to 60 FPS or 120 FPS with negligible CPU draw. Measuring idle state is trivial—the true test comes under thread saturation.
Impeller
Maintains a rock-solid 120 FPS on high-refresh panels. Because Impeller bypasses OS view hierarchies and writes straight to a GPU surface, raster times reliably stay within 2.5ms to 4.0ms—giving the GPU massive safety margin under the strict 8.3ms frame budget required for 120Hz.
Fabric
Achieves 120 FPS on simple layouts, but frame timing fluctuates during complex state changes. If JavaScript thread tasks spill past 8.3ms, the OS misses the VSYNC hit, triggering micro-dips down to 90 FPS.
| Benchmark Scenario | Flutter Impeller Frame Jank % | React Native Fabric Frame Jank % |
|---|---|---|
| First-Load Animation (Cold Start Shaders) | < 0.2% | < 0.5% |
| Heavy List Scroll (10k items with remote images) | 0.8% | 1.8% |
| Complex Canvas Animations + Blurs | 1.2% | 4.5% |
| Concurrent Heavy Parsing + UI Motion | 0.5% (Dart Isolate) | 3.2% (Thread Contention) |
Impeller completely cured Flutter's shader compilation jank. Fabric eliminated legacy bridge stuttering, but rapid list scrolling still incurs minor frame spikes on Android when mounting large clusters of platform native views.
Architecture dictates the memory baseline.
Flutter Impeller: ~42 MB – 55 MB RAM
React Native Fabric: ~28 MB – 36 MB RAM
Flutter incurs an upfront memory penalty because it must initialize the Impeller engine context, host runtime, and shader pipelines inside the app process. React Native leverages the native OS view system, giving it a lighter cold-start footprint.

When scrolling thousands of dynamic list cards, React Native's memory footprint spikes higher than Flutter's. Native platform views carry high object allocation costs. Fabric recycles views aggressively, but a dense tree of real UIViews consumes significantly more heap memory than Flutter storing pixel texture buffers managed directly by Impeller.
Dart VM
Uses a generational mark-sweep collector designed for heavy object churn. Heavy background workloads run in separate Dart Isolates with dedicated heaps, ensuring background GC passes don't pause the main rendering pipeline.
Hermes Engine
Engineered for fast startup and low heap footprint. While vastly superior to legacy JavaScriptCore, Hermes GC passes can still coincide with rapid state updates during heavy scroll events, causing micro frame drops.
React Native (Hermes AOT Bytecode)
~240ms (iOS) / ~310ms (Android). Hermes pre-compiles JavaScript source code into optimized bytecode at build time. The JS runtime boots almost instantly.
Flutter (Dart AOT Native)
~280ms (iOS) / ~380ms (Android). Dart compiles directly to native machine code, but initializing the Impeller engine and setting up GPU contexts adds a brief 40ms–70ms delay before drawing the initial frame.
Flutter (Impeller)
Offloads work from the CPU to the GPU early. CPU usage stays around 15%–25% during complex animations, resulting in lower battery draw (~3.5% drop over a 15-minute animation stress test).
React Native (Fabric)
Processes layout in C++ (Yoga) and passes instances to the OS view tree, pulling 35%–50% CPU load during rapid re-layouts. This pushes battery drain slightly higher (~5.0% drop over the same 15-minute test session).
Minimal Hello World Release App Size
Flutter Impeller: [========== 12.5 MB (APK) / 16.0 MB (IPA) ==========]
React Native Fabric: [====== 8.5 MB (APK) / 11.0 MB (IPA) ======]Flutter bundles the rendering engine inside every binary. React Native relies on host OS native views, yielding smaller download packages.
| Metric / Category | Flutter 3.27+ (Impeller) | React Native 0.76+ (Fabric) | Tactical Advantage |
|---|---|---|---|
| Shader Compilation Jank | Zero (Build-time compilation) | N/A (Uses Native OS Views) | Flutter (Impeller) |
| Frame Rate Stability (120Hz) | Locked 120 FPS | 90–120 FPS Variable | Flutter (Impeller) |
| Cold Start Baseline RAM | Higher (~42-55 MB) | Lower (~28-36 MB) | React Native (Fabric) |
| Heavy Load Memory Control | Predictable GPU allocations | Spikes under view-heavy lists | Flutter (Impeller) |
| Cold App Boot Time | Slower by ~50-70ms | Faster (Hermes Bytecode) | React Native (Fabric) |
| App Download Binary Size | ~12.5 MB Minimum | ~8.5 MB Minimum | React Native (Fabric) |
| OS Platform Fidelity | Custom rendered pixel copy | Genuine platform views | React Native (Fabric) |
Choose Flutter with Impeller if your app relies on custom visual design. If you are building graphic-heavy platforms, custom design systems, or apps requiring guaranteed 120 FPS motion consistency that renders identically down to the exact pixel on every Android manufacturer, Impeller is the superior engine. You trade larger download sizes and baseline RAM to eliminate rendering jank and OS layout bugs entirely.
Choose React Native with the New Architecture if you are building enterprise data platforms, e-commerce apps, or tools where platform native UI fidelity is paramount. If your application relies on native system behaviors—such as OS text selection, native accessibility trees, auto-fill primitives, or embedding seamlessly within existing native iOS/Android codebases—Fabric delivers high performance without forcing you to bundle an entire custom engine.