流言終結者- Flutter和RN誰才是更好的跨端開發方案?
背景
論壇上很多小夥伴關心為什麼閒魚選擇了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]
[REACT NATIVE]
場景
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
iPhone 6s 10.3.2
測試結論
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
Sumsung S8 7.0
注: 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&流暢度:
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 記憶體獲取方式:測試過程中使用的是physfootprint,是最準確的實體記憶體,很多開源軟體用的是residentsize(這個值代表的是常駐記憶體,並不能很好地表現出真實記憶體變化,這可以另開文章細談)
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;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900359/viewspace-2287163/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於 /dev/urandom 的流言終結devrandom
- Android流言終結者--xposed生效需要root嗎??不用!!Android
- 終結IT業七大流言
- flutter跨平臺開發之App升級方案FlutterAPP
- 網路音樂付費下載 誰才是最終受益者?
- 跨終端 WebWeb
- java和Python的這場紛爭,誰才是最終的人生贏家JavaPython
- [譯] 使用 Flutter 實現跨平臺移動端開發Flutter
- 你真的知道誰才是更好的免費OA工作流設計嗎?
- Flutter 到底能不能成為“跨平臺開發終極之選”?Flutter
- TypeScript, Angular 和移動端的跨平臺開發TypeScriptAngular
- Flutter-國際化適配終結者Flutter
- Flutter VS React Native VS Native,誰才是效能之王FlutterReact Native
- 跨終端設計模式設計模式
- Flutter元件化開發方案Flutter元件化
- (new)Flutter-國際化適配終結者Flutter
- [- Flutter 跨界篇-]昨晚簡記+Flutter桌面、Web開發FlutterWeb
- 【Mac】iTerm2 一個更好用的終端Mac
- Flutter 開發小結Flutter
- 00-跨平臺開發之FlutterFlutter
- 跨平臺開發Flutter初體驗Flutter
- 誰才是真正的資深開發者?
- 淺談 2018 移動端跨平臺開發方案
- 移動終端開發工程師工作流程的總結工程師
- [譯] Java、Kotlin、RN、Flutter 開發出來的 App 大小,你瞭解過嗎?JavaKotlinFlutterAPP
- Web前端開發與iOS終端開發的異同Web前端iOS
- 最火移動端跨平臺方案盤點:ReactNative、weex、FlutterReactFlutter
- 誰告訴你 Flutter 會幹掉原生開發?Flutter
- 開源一個Flutter編寫的完整終端模擬器Flutter
- 跨端開發框架深度橫評跨端框架
- 大家開發 RN 都用什麼?
- Flutter + Rust 高效能的跨端嘗試FlutterRust跨端
- 對比Memcached和Redis,誰才是適合你的快取?Redis快取
- wxPython和PyQt誰才是最讚的Python GUI庫PythonQTGUI
- NOW直播——Flutter元件化開發方案Flutter元件化
- 使用Flutter開發Github客戶端及學習歷程的小結FlutterGithub客戶端
- 一種方便的跨域開發解決方案跨域
- 誰需要 GUI?—— Linux 終端生存之道GUILinux