There are two key players in the cross-platform app development marketplace, and comparisons between the two abound. Questions about which is the more popular framework, which is easiest to work with, easiest to learn, which delivers better-performing apps, and which allows faster app development are explored constantly. For this article, we’ll look at several different performance assessments, and try to definitively answer the question: is Flutter fast?
What do we mean by fast? Because many of the external studies we look at are focused on Flutter app performance, often in comparison with React Native or Native app performance, that will be the primary focus. But when the study provides an answer, we’ll look at the speed of development as well (how long it takes to build a test app, for example).
Let’s take a look at some performance tests.
Flutter uses Dart programming language but provides an ahead-of-time compiler that generates native code to improve Flutter app performance to native or near-native levels. A Flutter app is compiled using the ARM C/C++ library. Unlike React Native, not just the UI components are compiled, but the entire app. This is one reason that, in general, Flutter apps are seen to be more performant. But let’s put this to the test.
Our first performance comparison is between React Native and Flutter found in a research paper done as a bachelor thesis by Jakub Jagiello in 2019. This is also one of the older performance comparisons, so bear in mind that this was performed prior to rendering performance improvements within React Native as well as a much earlier version of Flutter. The research paper also cites previous data from experiments done comparing React Native to native app performance.
In this paper, we see in-depth coverage of how React Native and Flutter operate, from coding language differences to GPU performance and state and rendering throughput. While analyzing performance metrics, it describes possible reasons for the differences. It describes the differences in how each framework handles individual app threads, such as the UI thread, and the GPU thread. It also explains the similarities, for example between components in React Native and widgets in a Flutter app. In both, the component or widget saves all the data you wish to store, and when the state changes, it is marked dirty. Marking itself as dirty tells the framework that the state has changed and needs to be re-rendered. This similarity allows for control over how often the framework has to work and re-render itself, aiding the performance test. The test measured how quickly the apps performed these re-renders on demand.
Two separate but related apps were tested to obtain the results of this paper, run on a physical device with all background apps suspended to provide accurate results. The test utilized the respective internal performance monitors of each platform. If a frame took longer than 16 milliseconds, it could safely be considered as ‘dropped’. Another metric used is an average time for rendering frames to allow the difference between dropped frames and successful frames to be measured. The apps in question contained only elements directly from the frameworks, without third-party libraries to potentially influence the results. Both frameworks were tested using debug mode, while Flutter was tested in production mode. React Native’s performance monitor did not allow the tests required to be performed outside of debug mode.
Noting challenges with the lack of a single performance monitor for both frameworks, the results pointed to better performance (by a slim margin) at a higher workload. The overhead of debug mode seemed to favor React Native and deliver a more steady result. Comparing the production results to the debug mode results did not show an appreciable difference.
In this article, Flutter and React Native are tested again, with the goal of comparing frames per second performance between both frameworks.
For this comparison, a single card app with a set list of 300 items in length was created using both React Native and Flutter. The same tests were performed on the same device, with the primary metric analyzed being frames per second within a particular timeframe.
The tests performed included:
The author also noted the time to create the applications is also noted, allowing us to consider the delivery of the app separately from the performance metric.
The time for the first image to load, and the app to become usable clearly favored Flutter in this test. Within the first two seconds, the Flutter app’s performance showed a frame rate of 39 FPS, while React Native’s app performance showed a rate of just 1 FPS.
Similarly, while less dramatic, React Native showed greater variance in FPS throughout the timeframe once scrolling rapidly through the app, with the tester noticing visual differences between the two apps as well. Flutter offered a smooth visual experience while React Native, if you will pardon the pun, fluttered. The test results bear this perception out, showing fluctuation between the two.
FPS test results for React Native vs. Flutter.
From the implementation perspective, the author notes that he found React Native easier to work with, though this is due to familiarity with JavaScript. Familiarity with JavaScript allowed him to stand up the application using React Native in less than half the time of Flutter. Given equal familiarity with both frameworks, it is impossible to know whether this result would be matched or improved upon. However, considering the prevalence of React Native and JavaScript familiar developers in the marketplace, familiarity might be a consideration when choosing between frameworks.
In the Inverita performance test article, the writer compares the performance of Flutter code, React Native code, and prominent native code types for each mobile platform.
For this test, the primary indicators of performance tested are memory usage and CPU usage. For each framework or codebase, an app using the Gauss–Legendre and Borwein algorithms of calculating Pi was used. Pi was calculated 100 times with 10 million digits precision. The test was run several times and an average of the results was used for each application. While both tests were CPU intensive, the Gauss-Legendre algorithm is more memory intensive. To measure more purely CPU-intensive operations, the Borwein algorithm was used.
For the memory-intensive Gauss-Legendre calculation on iOS, results showed that the best results were obtained on Objective C, and surprisingly, Flutter was a close second, over and above the native Swift option. React Native was a great deal slower, 20 times slower than Objective C.
For the more CPU-intensive Borwein algorithm on iOS, the results again showed Objective C to be the best result for intense calculations, with Swift close behind. For CPU-intensive operations, both Flutter and React Native lagged behind, with React Native just over 3 times slower than Flutter.
On the Android side, the same tests were performed. For the memory-intensive Gauss-Legendre calculation, React Native, Flutter, Java, and Kotlin were put head to head. Java and Kotlin tested almost identically (a difference of 1 ms). Flutter tested approximately 50 milliseconds slower, while React Native performed about 15 times slower than the native code options.
For the more CPU-intensive Borwein algorithm, the results were similar, though not as dramatic. Java and Kotlin again produced negligible differences from each other, just under 2 times faster than Flutter, and 6 times faster than React Native.
From this set of tests, we can determine that at least for CPU and memory-intensive performance, native coding performs best, and of the two primary cross-platform development frameworks, Flutter’s performance makes it the best choice. But as the article outlines in the beginning, this is a narrow definition of performance. This does not account for other types of performance profiling, such as rendering the user interface, interactions with the phone OS, business logic, etc. For this reason, a follow-up article was provided, to test these additional factors.
When Inverita published the results of the CPU-intensive calculations test, many responses outlined why this was not the best benchmark to use. For this reason, a deeper performance study was performed, measuring various costly performance operations on React Native, Flutter, and Native applications. Operations tested include List view scrolling benchmarking, heavy animation testing, and another test involving a large number of basic animations (200 basic animations).
The same UI was created for Android and iOS using React Native, Flutter, and Native code. The app developers then automated scroll velocity with RecyclerView.SmoothScroller for Android, and ScrollController for iOS. For both, they used a timer and programmatically scrolled to position. One thousand list items were provided, and the same scrolling time to reach the last element. Nuke was used as a caching library for iOS platforms, and Glide for Android. For the React Native apps, React-native-fast-app was used. GPU usage could not be measured for Android.
Android benchmarking test results.
On Android, all three versions of the app showed approximately the same FPS. However, for both React Native and Flutter, CPU, Memory, and Battery usage were all higher than for Native. React Native used more CPU, Memory, and Battery power than Flutter.
iOS benchmarking test results.
For iOS, we again see that all show approximately the same FPS. React Native lags behind both Flutter and Native, particularly in CPU usage and memory usage. Native engages the GPU more than both cross-platform frameworks, while Flutter engaged the CPU more. Memory usage for Flutter nearly mirrored native.
Because most phones have more powerful hardware these days, FPS drops are usually not noticed for business applications. For this reason, a test with vector animations heavy enough to drop FPS was created, in order to test the performance of Flutter applications, React Native applications, and native apps. Lottie was used for React Native, Android, and iOS, while Flare was used for Flutter.
Android heavy animation test results.
For this test, React Native and Native come out on top, with very similar FPS and CPU usage. This is not a big surprise, because React Native leverages native components. Flutter lags behind in FPS. Flutter and React Native both lag behind Native in terms of memory usage. React Native took up the most memory but considering the difference in FPS between React Native and Flutter, the difference would be considered negligible. Surprisingly, native code would drain battery life the quickest, according to this test. Flutter’s FPS performance is likely due to the Flare package being less optimized for this type of test.
iOS heavy animation test results.
We see similar results for iOS, with React Native and Native displaying similar FPS results. React Native shows better CPU performance than both Flutter and Native, but lags behind both in memory usage. Flutter’s FPS performance is dismal in comparison but uses marginally less GPU and memory than React Native. For iOS, React Native and Flutter both use slightly more battery life.
The final test performed tested a large number of basic animations, rather than resource-intensive vector animations. Two hundred separate lightweight images were used, animated to show both scale rotating and fading animations.
Android animation in quantity test results.
For this test, Native provided the best performance by a fair margin. Not only did it provide the best FPS results, it used the least memory and CPU. Flutter was the next best performer, using marginally more CPU, but less than half the memory, and delivering almost 3 times the FPS of React Native, which did not fare well at all.
iOS animation in quantity test results.
On iOS, the iPhone tested proved powerful enough not to lose FPS on native or cross-platform frameworks. It is likely no surprise that the native app used the least resources, and of the resources used, relied mostly on the GPU. Flutter offered the next best memory performance, relying even more heavily on the GPU than native. React Native used the GPU least, but had the heaviest CPU and memory usage.
Thoughtbot’s test involved the creation of essentially the same application using native code, React Native, and Flutter on Android devices. The app in question is a simple timer app, which counts upwards from the point initiated, till stopped.
Tests were run on a Nexus 5 and a Pixel device, with all three apps on each device. The test was run on each app in turn, testing the CPU and memory resources used by each.
The application did not require a lot of resources on either mobile device but showed a clear advantage to native code for each, particularly on memory. On the Nexus 5, memory usage favored React Native over Flutter, while CPU usage favored Flutter. However, the writer was surprised at how close the performance stats were.
For the Pixel test, the results were surprising, because the Pixel phone is typically seen as a more powerful phone, and it was expected that CPU usage would be less, rather than more. In addition to the surprise of the intensity of CPU usage, the test showed significant differences in how the two cross-platform frameworks operated, with React Native using marginally more memory in comparison with the Native code, with Flutter memory usage being over 50% higher. For CPU, the Flutter app closely matched native code, while React Native struggled to stay below 30%. Again, overall, the cross-platform frameworks performed very similarly, with slight differences in how this performance was achieved. The test of the timer app seemed to highlight more the differences between devices rather than app performance.
In nearly all the tests that proved conclusive, Flutter is indeed fast, nearly matching native code in some instances. SudoLabs noted distinct advantages in startup time and performance for Flutter, and inconsistency in React Native’s performance when rendering frames. Inveritas noted a distinct advantage for Flutter when it came to apps that performed heavy-duty computations. When it came time to render frames and perform list view scrolling, FPS results were largely the same, with React Native using significantly more memory and CPU to obtain the same frame rate. As most of the tests attempted to avoid unnecessary third-party libraries to measure the cross-platform frameworks alone, opportunities to improve performance on either Flutter or React Native may have been limited. For example, Flutter faltered heavily when it came to heavy animations, but this was attributed to a weakness in the third-party library used by Flare. If this is true, this indicates a separate problem, but one definitely worth considering – a weakness in the availability or performance of third-party packages can be a strong reason to consider React Native deployment in certain situations. Third-party libraries can be used for performance optimization in certain tasks. In addition to this, the prevalence of JavaScript-familiar developers and a general sense that Flutter takes marginally longer to deliver an app (if less familiar with Dart and Flutter) can be deciding factors for your organization.
However, this does not negate that in general, Flutter is indeed fast. Flutter developers can benefit from numerous features designed to speed up the app development process, particularly design, which over time, might eliminate the development speed advantage mentioned by JavaScript familiar developers. Flutter showed significant differences in performance metrics, matching or exceeding React Native in a clear majority of the tests shown above, with the notable exception being heavy animation. In some cases, the difference was in how the frameworks delivered performance, whether via heavy use of memory or CPU and where it could be measured, GPU performance. Overall, there was little difference in FPS, but to deliver the same results, React Native tended to use more system resources, and according to InVerita, used more battery power.
Create visually stunning and functionally robust apps with Flatirons' Flutter development services.
Learn moreCreate visually stunning and functionally robust apps with Flatirons' Flutter development services.
Learn moreFlatirons
Sep 18, 2024Flatirons
Sep 16, 2024Flatirons
Sep 14, 2024Flatirons
Sep 12, 2024Flatirons
Sep 12, 2024Flatirons
Sep 09, 2024