The real cost of React Native animations: benchmarking every approach
Key Points
- Ease yields ~0ms UI-thread cost on iOS
- Reanimated costs explode in debug builds
- Synchronous UI-prop flags cut Reanimated overhead 11–19%
Summary
A benchmark comparing four React Native animation approaches (react-native-ease, Reanimated shared values, Reanimated CSS, and RN Animated) measured per-frame UI-thread overhead on iOS (iPhone 15 Pro) and Android (Moto G8 Plus). Tests (Apr 2026) used Expo SDK 55, React Native 0.83, Reanimated 4.3.0, and react-native-ease 0.7.0. Main finding: on iOS, driving animations via platform APIs (Core Animation) yields effectively zero UI-thread cost; on Android all engines run on the UI thread so overhead matters and scales with view count. Reanimated performance is highly sensitive to debug vs release builds and benefits from synchronous UI-prop flags or the upcoming RN 0.85 Shared Animation Backend.
Key Points
- Architecture matters: Ease (react-native-ease) hands animations to platform renderers (Core Animation on iOS, ObjectAnimator on Android). On iOS this results in ~0.01ms UI-thread cost because the OS render server drives frames outside the app.
- Android parity: on Android every approach runs on the UI thread, so measured per-frame overhead is a direct cost. Ease is not free on Android; it still occupies the UI thread.
- Debug vs Release: Reanimated shows dramatically higher overhead in debug builds. Reproduce performance in release builds first (debug builds can be misleading).
- Scaling behavior: at 10–100 animated views most libraries average under 16.67ms, but at ~100 views Reanimated and RN Animated approach the frame budget with little headroom. At 500 views only Ease stayed under budget on the tested devices.
- Shadow-tree tax & flags: Reanimated computes values and commits props through the shadow tree every frame, triggering Yoga/layout work even for visual-only props. ANDROID_SYNCHRONOUSLY_UPDATE_UI_PROPS and IOS_SYNCHRONOUSLY_UPDATE_UI_PROPS bypass shadow commits and reduced Reanimated per-frame cost by ~11–19% in tests.
- Use cases: prefer platform-driven (Ease) animations for long-running, ambient, or non-gesture visual effects (drifting backgrounds, skeleton loaders). Use Reanimated or RN Animated for gesture-driven or layout-changing animations.
How it was measured
- Measurement: CADisplayLink interception on iOS and Window.OnFrameMetricsAvailableListener on Android; 5-second collection windows per test.
- Repo: benchmark is in the example app (example/src/demos/BenchmarkDemo.tsx). Run in release builds:
yarn example ios --configuration Releaseoryarn example android --variant release.
Practical recommendations for engineers
- Always test animations in release builds and on representative low-end devices.
- For iOS ambient/long-running visual effects, prefer CA-backed libraries (react-native-ease) to remove per-frame UI-thread cost.
- On Android, minimize concurrent animated views, enable Reanimated synchronous UI-prop flags to reduce overhead (test for visual regressions), and watch for RN 0.85 Shared Animation Backend to land in your stack.
- Reserve Reanimated for gesture/interactive or layout animations where JS/worklets must drive values mid-flight.
Quick reference
- Benchmarks: Apr 2026, Expo SDK 55, RN 0.83
- Libraries: react-native-ease 0.7.0, Reanimated 4.3.0