Achieving 60 FPS in React Native with Imperative Manipulation
Article Summary
Sourav Yadav from Razorpay discovered that React Native's declarative approach was causing frame rates to plummet to 0 FPS. His solution? Break the rules and go imperative.
React Native's declarative API is convenient, but it comes with a hidden cost: the reconciliation algorithm can become a performance bottleneck when dealing with thousands of nodes. Razorpay's engineering team tested both declarative and imperative approaches to find where the breaking point occurs and how to fix it.
Key Takeaways
- With 3000 animated nodes, declarative updates dropped to 0 FPS on JS thread
- Imperative manipulation using setNativeProps bypasses React's reconciliation overhead entirely
- UI thread maintained 60 FPS imperatively vs dropping to 38 FPS declaratively
- Trade-off: imperative nodes stay in memory even when hidden, increasing consumption
Critical Insight
When React Native apps hit performance walls with complex UIs, setNativeProps can maintain 60 FPS by skipping reconciliation, but only use it as a last resort after exhausting declarative optimizations.