移动性能测试 [转] 流言终结者- Flutter 和 RN 谁才是更好的跨端开发方案?

小王子 · 2018年09月10日 · 最后由 会说话的汤姆猫 回复于 2018年11月06日 · 5187 次阅读
本帖已被设为精华帖!

转自 https://mp.weixin.qq.com/s/XSfPs2hX2P7FPqRUyematA

背景

论坛上很多小伙伴关心为什么闲鱼选择了 Flutter 而不选择其他跨端方案?站在质量的角度,高性能是一个很重的因素,我们使用 Flutter 重写了宝贝详情页之后,对比了 Flutter 和 Native 详情页的性能表现,结论是中高端机型上 Flutter 和 Native 不相上下,在低端机型上,Flutter 会比 Native 更加的流畅,其实闲鱼团队在使用 Flutter 做详情页过程中,没有更多地关注性能优化,为了更快地上线,也是优先功能的实现,不过测试结果出来之后,却出乎意料地优于原先的 Native 的实现 (具体的测试结果,属于敏感数据,要走披露流程,伤不起…)

但是这样很显然不能敷衍过去,仔细想了想,确实 Flutter 的定位并不是要替代 Native,他只想做一个极致的跨端解决方案,所以还是要回到跨端解决方案的赛道,给您从性能角度比一比,谁才是更好的跨端开发方案?

参赛选手

[Flutter]

Flutter is Google’s mobile app SDK for crafting high-quality native interfaces on iOS and Android in record time. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source.

[REACT NATIVE]

We're working on a large-scale rearchitecture of React Native to make it more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.

鸣锣开赛

怎么比

怎么比较确实伤脑筋,自己也写了一个 Flutter 和 一个 RN 的 App,但是实在太丑陋,担心大家关注点都到我的烂代码上了,所以在 Github 上找到了一个跨端开发高手 Car Guo,用 Flutter 和 RN 分别实现的一个实际可用的 App,Car Guo 谦虚表示其实也写的比较粗糙,但是在我看来这个是具备真实使用场景的 App(Github 客户端 App,提供丰富的功能,旨在更好的日常管理和维护个人 Github),还是有代表性的
[Flutter] https://github.com/CarGuo/GSYGithubAppFlutter
[REACT NATIVE] https://github.com/CarGuo/GSYGithubApp

场景

1、默认登录成功
2、“动态” 页,点击搜索按钮,搜索关键字 “Java”,正常速度浏览 3 页,等第 4 页加载完成后回退
3、点击 “趋势” 页 Tab,浏览 Feeds 到页面底部,点击最底部的 Item,进入 Item 后,浏览详情 + 浏览 3 页的动态后回退,到 “我的” Tab 页
4、查看 “我的” Feeds 到底部,点击右上角搜索按钮,搜索关键字 “C”,浏览 3 页后,等第 4 页加载完成后场景结束

测试工具

  • iOS
  • 掌中测 (iOS 端):CPU,内存
  • Instruments:FPS
  • Android
  • 基于 Adb 的 Shell 脚本:CPU,内存,FPS

测试机型

  • iOS:iPhone 5c 9.0.1 / iPhone 6s 10.3.2
  • Android:Xiaomi 2s 5.0.2 / Sumsung S8 7.0

数据分析

iOS

iPhone 5c 9.0.1

image.png

iPhone 6s 10.3.2

image.png

测试结论

1、Flutter 在低端和中端的 iOS 机型上,FPS 的表现都优于 RN
2、CPU 的使用上 Flutter 在低端机上表现略差于 RN,中端机型略优于 RN
3、值得注意的是内存上的表现 (上图红色箭头区域),Flutter 在低端机型上的起始内存和 RN 几乎一致,在中端机型上会多 30M 左右的内存 (分析为 Dart VM 的内存),可以想到这应该是 Flutter 针对低端和中端机型上内存策略是不一样的,可用内存少的机型,Dart VM 的初始内存少,运行时进行分配 (这样也可以理解为什么在低端机上带来了更多的 CPU 损耗),中端机器上预分配了更多的 VM 内存,这样在处理时会更加的游刃有余,减少 CPU 的介入,带来更流畅的体验.
可以看出,Flutter 团队在针对不同机型上处理更加的细腻,目的就是为了带来稳定流畅的体验。

Android

Xiaomi 2s 5.0.2

image.png

Sumsung S8 7.0

image.png

  • 注: MFS - Max Frame Space: 指的是去掉 buffer 之后的两帧的时间差

测试结论

1、Flutter 在高低端机的 CPU 上的表现都优于 RN,尤其在低端的小米 2s 上有着更优的表现
2、Android 端在原来 FPS 基础上增加了流畅度的指标,FPS 和流畅度的表现 Flutter 优于 RN(计算规则见附参考文章)
3、Android 端的内存也是值得关注的一点,在小米 2s 上起始内存 Flutter 明显比 RN 多 40M,RN 在测试过程中内存飞涨,Flutter 相比之下会更稳定,内存上 RN 侧的代码是需要调优的,同一套代码 Flutter 在 Android 和 iOS 上并没有很大的差异,但是 RN 的却要在单端调优,Flutter 在这项比拼上又更胜一筹。
比较奇怪的是三星 S8 上 Flutter 和 RN 的初始内存是一致的,猜测是 RN 也 Android 高端机型上也会预分配一些内存,具体细节还需要更进一步的研究。

升旗仪式

看了之前的数据,做为裁判的我会把金牌颁给 Flutter,在测试过程中的体验和数据上来看 Flutter 都优于 RN,并且开发这个 App 的是一位 Android 的开发同学,Flutter 和 RN 对于他来说都是全新的技术栈,Car Guo 同学更倾向性地让大家得到一致性的使用体验,性能方面并没有投入太多的时间进行调优,由此看出 Flutter 在跨端开发上在同样投入的情况下,可以获得更佳的性能,更好的用户体验。

一些思考

拿到了这些数据,也感受到 Flutter 带来福利,那 Flutter 为什么可以做到这么流畅呢?Flutter 是如何优化了渲染,Dart VM 的 Runtime 是怎么玩的?请大家继续关注后续解密文章,感兴趣的同学欢迎加入闲鱼,成为跨端解决方案的领军者。

参考

  • Android FPS&流畅度: https://testerhome.com/topics/4775
  • Android 内存获取方式:
    dumpsys meminfo packageName

  • Android CPU 通过 busybox 执行 top 命令获取

  • iOS CPU 获取方式:累计每个线程中的 CPU 利用率

for (j = 0; j < thread_count; j++)
{
ATCPUDO *cpuDO = [[ATCPUDO alloc] init];
char name[256];
pthread_t pt = pthread_from_mach_thread_np(thread_list[j]);
if (pt) {
name[0] = '\0';
__unused int rc = pthread_getname_np(pt, name, sizeof name);
cpuDO.threadid = thread_list[j];
cpuDO.identify = [NSString stringWithFormat:@"%s",name];
} 
thread_info_count = THREAD_INFO_MAX;
kr = thread_info(thread_list[j], THREAD_BASIC_INFO,(thread_info_t)thinfo, &thread_info_count);
if (kr != KERN_SUCCESS) {
return nil;
}
basic_info_th = (thread_basic_info_t)thinfo;
if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
cpuDO.usage = basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
if (container) {
[container addObject:cpuDO];
}
}
}   
  • iOS 内存获取方式:测试过程中使用的是 phys_footprint,是最准确的物理内存,很多开源软件用的是 resident_size(这个值代表的是常驻内存,并不能很好地表现出真实内存变化,这可以另开文章细谈)
if ([[UIDevice currentDevice].systemVersion intValue] < 10) {
kern_return_t kr;
mach_msg_type_number_t info_count;
task_vm_info_data_t vm_info;
info_count = TASK_VM_INFO_COUNT;
kr = task_info(mach_task_self(), TASK_VM_INFO_PURGEABLE, (task_info_t)&vm_info,&info_count);
if (kr == KERN_SUCCESS) {
return (vm_size_t)(vm_info.internal + vm_info.compressed - vm_info.purgeable_volatile_pmap);
}
return 0;
}

task_vm_info_data_t vmInfo;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
if (result != KERN_SUCCESS)
return 0;
return (vm_size_t)vmInfo.phys_footprint;
共收到 11 条回复 时间 点赞

感谢分享,我们内部 app 最近都在用 Flutter 重写

国文 回复

赞,后续可以交流 flutter 的测试,wigdet test 和 integration test 的玩法现在业界还是很少的

dart 好用吗

今天按照 flutter 的教程进行的 编译运行阶段突然卡住了,截图如下

试了的速度比较慢)也没有解决。

codeskyblue 回复

你这个看起来是 gradle 下载失败? 你可以用本地的 gradle 下一下,不要从网上下。
flutter 程序根目录执行 flutter doctor 命令,发出来看看

小王子 回复
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel beta, v0.7.3, on Microsoft Windows [Version 10.0.16299.125], locale zh-CN)
[√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[√] Android Studio (version 3.1)
[√] Connected devices (1 available)

• No issues found!

本地的 gradle 该怎么弄,求指导

codeskyblue 回复

就是配置一个 gradle 的环境,然后配置 gradle 环境变量,在命令行直接 gradle 编译吧

仅楼主可见
恒温 将本帖设为了精华贴 09月15日 08:33
codeskyblue 回复


你是用 Android studio 是吗? 在这边配置一下你本地下载好的

你可以问一下 浮云...
如果你可以在 windows 下可以用 pycharm 打开看一下 是不是 constants 没有下载,是不是要 pip install constants,
不过还是建议你看一下 浮云实现的代码逻辑

都是坑货 我们公司就实行 rn 不想说了

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 14:44
simple [精彩盘点] TesterHome 社区 2018 年 度精华帖 中提及了此贴 01月07日 12:08
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册