谈到移动应用开发时,人们常常会讨论选择Flutter还是React Native,这更多是基于性能的考量。虽然两个框架都有其支持者,但我们很多人更关心实际的基准测试结果,尤其是对于那些拥有复杂界面和用户体验的应用来说。
我们惊讶地发现很少有关于 Flutter 和 React Native 的基准测试对比,而且即使是有的,也比较陈旧。因此,使用当前版本的 Flutter 和 React Native,这里提供了一个关于 App 大小、内存和 CPU 使用情况 的全面基准测试对比。结果非常有趣,甚至可以说是相当令人惊讶的。
常用应用三种类型的 app 被纳入了基准测试:
- 包含1000个项目的大型列表视图:每个项目包括一张静态图片和一张不断旋转的图片。
- 批量图片动画:200张图片同时进行旋转、淡入淡出和缩放。
- 批量Lottie动画:一个屏幕上同时展示36个Lottie动画。
- 每个基准测试都在一个 M1 Mac 上进行。
- 在Android设备上,基准测试应用运行在Oneplus 7上,在iOS设备上,则运行在iPhone 8和iPhone 15上。
- 在Android中,使用Android Profiler测量了flutter和React Native的发布版apk的内存和CPU使用情况。
- 在iOS中,每个基准测试应用程序都以发布模式运行。内存和CPU使用情况分别通过Allocations和Time Profiler工具进行测量。
- FPS在Flutter应用的“profile模式”中测量,对于React Native,则在JS最小化并且开发模式已关闭的构建中测量,但保持metro捆绑器连接状态。(由于React Native的性能统计仅在连接到metro捆绑器时有效)
- 这里是基准测试的源代码:https://github.com/nateshmbhat/flutter-rn-performance-benchmarks
- 至于动画,Flutter使用内置的Animation API,而React Native则使用行业标准的Reanimated v3。
使用的框架版本如下:
React Native:0.74.1 | Flutter:3.19.5 | Dart:3.3.3
列表视图的性能这款应用使用了Flutter内建的ListView和Animated API。在React Native中使用了最新的Reanimated v3库和内置的FlatList。这两个列表都是直接拿来使用,没有进行显式的优化或设置固定高度。
Android:Android列表性能测试
Flutter
- FPS: 60(无卡顿)
- Dart 堆内存使用:7–8 MB
- APK 大小:16.8 MB(构建时间 7.6 秒)
- 进程内存:120–130 MB(滚动时保持不变)
- CPU:5–8%(滚动时保持不变)
- 即使快速滚动也没有卡顿或掉帧
React Native :
- FPS: 50–55(较为明显的卡顿感)
- APK 大小:21.9 MB(构建所需时间为 23 秒)
- 内存:未滚动时为 160 MB,滚动时为 180–190 MB
- CPU:未滚动时为 11–13%,滚动时升至 25–30%
- 滚动时偶尔会出现帧丢失和空白项
iOS 列表项性能测试
Flutter:
- 内存使用:
iPhone8 : 48 MB(滚动时内存保持48 MB)
iPhone15: 93 MB(滚动时内存保持93 MB) - CPU使用率: 40–60%(滚动时保持不变)
- 快速滚动时没有卡顿或掉帧
- 压缩包大小: 71.5 MB(构建时间: 30秒)
React原生
- 内存:
iPhone8:1.05 GB,滚动时降至大约453 MB。
iPhone15:1.12 GB,滚动时降至大约430 MB。 - CPU:120–140%,前5秒,然后在不滚动时降至约50%。滚动时飙升到140–150%。
- 没有掉帧,但有时在快速滚动时会突然停止,(用户需要重新滚动)
- 压缩包大小:112.3 MB(构建耗时:318秒)
Android :Flutter 在滚动时非常流畅,没有出现内存或 CPU 使用激增,而 React Native 在滚动时则出现了帧丢失,并且 CPU 和内存使用也出现了显著的激增。
IOS : 在 React Native 中,内存占用非常高。Flutter 使用最少的内存和 CPU 资源。有趣的是,在 iOS 上,内存使用情况与 Android 不同,滚动时,React Native 的内存使用量减少到一半,而 CPU 却激增。
批量图片动画效果 安卓Android 大批量图片动画测试结果
Flutter
- FPS: 58–60,
- Dart 堆大小: 13.4 MB
- APK 大小: 11.6 MB (构建时间 19.6 秒)
- 内存: 128–135 MB
- CPU: 8%
React原生
- FPS: 58–60(偶尔会掉帧)
- APK 大小:21 MB(构建只需 20 秒)
- 内存:380–396 MB
- CPU 占用:12–16%
Flutter:
- 内存:
iPhone 8:49MB
iPhone 15:94MB - CPU:
iPhone 8:50–60%
iPhone 15:23% - 没有明显的卡顿或掉帧
- 归档大小:71.2MB(构建所需时间:33秒)
React Native(也就是React原生):
-
内存:
iPhone 8:1.2 GB(内存不足警告和可能崩溃)
iPhone 15:1.38 GB(无崩溃) -
CPU:
iPhone 8:135–140%(约几秒钟后可能崩溃)
iPhone 15:前3.5秒200–300%,然后降至50–60% -
iPhone 8 出现严重卡顿、掉帧和可能崩溃。iPhone 15 只有开始时卡顿
- 归档大小:112.3 MB(构建时间:317 秒)
Android :两个框架的FPS相似,但React Native在动画重新开始时FPS下降,并且内存使用量显著增加。
IOS : 高CPU和内存峰值非常高在React Native中,最终在旧款iPhone上崩溃。Flutter运行起来似乎没有问题,资源消耗较少。
大量 Lottie 动画 Android:大规模Lottie动画测试的结果
Flutter
- FPS: 36
- APK 大小:7.6 MB(构建时间 20.8 秒)
- 内存占用:220 MB
- CPU 占用率:11%
Android:
- FPS: 43
- APK 文件大小:18.5 MB(构建所需时间 23 秒)
- 内存占用:240 MB
- CPU 使用率:22%
Flutter:
- 内存:
iPhone8 : 150–165 MB
iPhone15 : 增加到255 MB 并保持不变 - CPU:
iPhone8 : 120–140%
iPhone15 : 50–70% - 存档大小: 72.9 MB (构建时间为29秒)
React Native:
- 内存:缓慢增至125MB后保持稳定(两部iPhone)
- CPU:
iPhone8: 达到100%持续6秒后降至50–60%
iPhone15: 60–80% - 归档文件大小:133.5MB(构建时长:304秒)
Android : React Native 的帧率比 Flutter 高,但其 CPU 和内存使用量也更高。
IOS: React Native相比Flutter占用的内存和CPU更少这一点。
入门项目的比较最新更新:根据 Flutter 最近发布的 3.22 版本文章,Lottie 的渲染性能在 Impeller 渲染引擎上有了显著提升。 此基准测试基于 Flutter 3.19.5。我还没在新版本的 Android 上用 Impeller 进行过这个基准测试。
当我们第一次在 react native 或 flutter 中创建一个项目时,我们发现了一个意外的情况:react native 的 apk 大小明显大于 flutter 项目的初始 apk 大小。
尽管这个特定案例不是一个完全公平的比较(因为两个启动程序是不同的),但它确实提供了一些有趣的观察,这些观察不应被纳入性能基准测试的结果中。
Android启动项目的构建时间和大小的对比
注意,使用React Native创建应用所需的时间较长,因为设置新项目时整个react-native库会被下载。而Flutter SDK在创建新应用之前就需要被获取。
最终裁决接下来:Android: 各项基准测试一致显示 Flutter 的 APK 大小更小,其 CPU 和内存使用情况比 React Native 更好一点点。
IOS: 与 Flutter 相比,React Native 的资源消耗非常高。但在大量 Lottie 动画应用中,Flutter 消耗更多资源。
- 使用带有 新架构 的 React Native 进行性能基准测试。
- 改进 iOS 数据指标的可视化效果。
即将发布的文章
很快会发布更详细的基准测试比较,以及内存和CPU使用情况的快照。所以,敬请期待!