The Story Behind the Research
As a custom software development company, inVerita and its mobile development team continuously dig into the performance of cross-platform mobile solutions available on the market, that’s how Flutter vs React Native vs Native Part I emerged. Yes, it was quite controversial as one can state we weren’t using React Native to perform multiple calculations daily — that might be the case — but in this case, CPU-heavy tasks are better performed by Flutter or native apps.
That’s why in this article we decided to research the performance of UI which has a much bigger impact on a daily user of mobile apps.
Measuring UI performance is complex and it requires an engineer to implement the same functionality in the same way across every platform. We went with a GameBench as a global testing tool to leave no doubts and make sure we stay objective (it doesn’t change the fact that we truly love Flutter in most aspects:) ). GameBench has a lot of space for improvements, but we managed to put every app into a single testing environment which was our goal.
Source code is open so please experiment and share your thoughts with us if you wish. UI animations mostly use different tools across different platforms so we narrowed everything to libraries supported by every platform (but one case) or at least we did everything we could to accomplish that. Test results can be different and depend on your approaches to the implementation, we believe that you, as a potentially true expert of specific technology can push your specific set of tools to the limits where it outperforms our numbers and we are happy if you do.
Now let's have a look at the cases.
Use Case 1
List view benchmarking.
We implemented the same UI on Android and iOS with the use of Native, React Native, and Flutter. We also automated scroll velocity with the use of RecyclerView.SmoothScroller on Android. On iOS and React Native we used an approach with a timer and programmatically scrolling to position. On Flutter, we used ScrollController to smoothly scroll over the list. In each case, we had 1000 items in the list view and the same scrolling time to reach the last list element. In each of these cases, we used image caching with different libs per platform. More details could be revealed in the source code.
Third-party libraries used:
- Loading and caching images — Nuke
- Loading and caching images — Glide
- Loading and caching images — React-native-fast-image
GPU tests results are not supported by the benchmark (unfortunately, with the devices we have, and we have many:)) )
- All tests have shown approximately the same FPS.
- Android Native uses half as much memory compared to Flutter and React Native.
- React Native requires the most significant CPU exploitation. The reason is the use of JSBridge between JS and Native code that incites the waste of resources on serialization and deserialization.
- Regarding battery exploitation, Android Native has the best outcome. React-native is lagging behind both Android and Flatter. Running continuous animations consumes more battery power on React Native.
iPhone 6s test
- FPS. React Native results are worse than those of Flutter and Swift. The reason is the inability to use IoT compilation on iOS;
- Memory. Flutter almost matches native in Memory consumption but is still heavier on CPU. React Native falls far behind Flutter and native in this test.
- Difference between Flutter and Swift. Flutter is actively using CPU when iOS Native is actively using GPU. Reconciliation in Flutter increases the load on the CPU.
Use case 2
Nowadays most phones running on Android and iOS have powerful hardware. In most cases using usual business apps, no fps drops could be noticed. That's why we decided to do some tests with heavy animations. Heavy enough to get fps drops. We used vector animations animated with Lottie on Android, iOS, React Native, and adopted the same animations to use with Flare on Flutter.
Android1) Android and React Native have similarities in their performance. It’s obvious because Lottie for React Native uses Native means (16-19% CPU, 30-29 FPS).
2) Flutter’s outcome is such a surprise, though it screwed up a bit during a performance (12% CPU and 9 FPS).
We discovered that removing one specific animation from the grid increases FPS up to 40% on Flutter. We suppose Flare is heavier and not optimized for this kind of task that’s why Flutter got such an FPS drop.
3) Android requires the least amount of memory (205 Mb); React Native needs 280 Mb and Flutter requires 266 Mb.
4) Cold app start. According to this indicator, Flutter is the leader (2 seconds). For Android Native and React Native, it takes around 4 seconds.
- iOS and React Native outcomes on this test are almost the same as Lottie for React Native uses native means.
- Flare and Flutter are not going to stop surprising. Flare definitely has a way to go :D
- iOS Native requires the least amount of memory (48 Mb). React Native needs 135 Mb and Flutter requires 117 Mb;
- Cold app start. According to this indicator, Flutter is the leader (2 seconds). For iOS and React Native it takes around 10 seconds;
Take a note: we used a different library for this case with Flutter which is much heavier compared to those we used for other platforms and it might be the reason for fps drops.
Use case 3
In this test, we compared performance while animating 200 images. Scale rotating and fade animations are executed at the same time.
- Native showed top performance and most efficient memory consumption.
- Flutter showed a very close to Native fps and twice more memory expenses but still a decent performance.
- React Native — shown a low performance on this case.
- iPhone 6s is powerful enough to not drop fps in all 3 cases.
- Native used fewer resources and GPU was used mostly.
- React Native used mostly CPU for rendering while Flutter used GPU.
- React Native used a bit more memory.
For our testing purposes, we were using an affordable Xiaomi Redmi Note 5 and an iPad Mini 3 (released in 2014) and iPhone 6s.
For usual business apps with minor animations and shiny looks, technology does not matter at all. But if you'll do some heavy animations keep in mind that Native has the most performance power to do it. Next, come Flutter and React Native. We would definitely not recommend using React Native in a very CPU heavy operation, while Flutter is a great fit for such tasks from both CPU and Memory standpoint.
The tool you pick depends on your specific product and business case. In case you are looking to develop a single-platform MVP — use native means, but keep in mind that Flutter apps can be built both for mobile, web and desktop environments and it feels like Flutter might become a King of cross-platform development in not too distant future, as even today Flutter created a very decent competition for native development tools, especially if your development budget is not too stretched but you are still looking for the decent performance of yours app.
We face the fact that there might be many factors impacting the implementation and benchmarks of each technology, and many of you who might be true experts of a specific platform can squeeze much more out of the beloved set of tools. We tried to bring as much transparency into the process as we could by creating a single environment for each app to get tested and a single set of tools to measure the performance, and I hope you liked the result. Yet again our mobile and Flutter teams are happy to receive and carry all the burden of your feedback and suggestions:).