作者 | InVerita

策劃 | 蔡芳芳

Flutter 是 Google 開源的移動用戶界面框架,可以快速在 iOS 和 Android 上構建高質量的原生用戶界面,正在被全球越來越多的開發者和組織使用。而 React Native(簡稱 RN)是 Facebook 開源的跨平臺移動應用開發框架,是 Facebook 早先開源的 JS 框架 React 在原生移動應用平臺的衍生產物,支持 iOS 和安卓兩大平臺。至於 Native,就是傳統的原生 App 開發模式。那麼問題來了,在這三種開發技術,我們該如何進行選型呢?本文將對這三種開發方案的性能進行深度對比,包括它們在多個應用場景下 FPS、CPU、內存和 GPU 方面的性能。希望對讀者有所幫助。

本文最初發表在 Medium 博客,經原作者 inVerta 公司授權,由 InfoQ 中文站翻譯並分享。

研究背景

inVerita 及其移動開發團隊不斷深入研究市場上可用的跨平臺移動解決方案的性能,以回答這樣一個問題:對於你的產品,甚至是你的職業生涯來說,Flutter、React Native(或 Native),哪種技術是最好的?這就是文章 《Flutter vs React Native vs Native:性能考察》 的由來。是的,這篇文章引發了一些爭議,因爲有人認爲,我們並沒有使用 React Native 每天進行很多次計算,但如果是這種情況,CPU 佔用率較高的任務由 Flutter 或 Native app 來完成會更好。

這也是爲什麼在本文中,我們決定研究用戶界面的性能,因爲它對移動應用程序的普通用戶影響更大。

衡量用戶界面性能很複雜,它需要工程師在每個平臺上以相同的方式實現相同的功能。我們選擇了 GameBench 作爲全局測試工具,以確保我們能夠保持客觀(這並不會改變我們在很多方面喜愛 Flutter 這一事實,並且我們也運行着大量 React Native 和 Native 項目)。儘管 GameBench 還有很大的改進空間,但是,在它的幫助下,我們還是成功地將每個應用程序放入一個單獨的測試環境中,這也是我們的目標。

源代碼是開源的,因此,如果你願意的話,可以自己做實驗並與我們分享你的想法。用戶界面的動畫通常在不同的平臺上使用不同的工具,所以我們將範圍限制在每個平臺(只有一種情況除外)都支持的庫中,或者至少我們已經盡己所能來實現這一點。現在,讓我們來看看這些用例。

硬件信息:爲完成這項測試,我們使用了價格實惠的手機:紅米 Note5 和 iPhone 6S。

GitHub 鏈接:

用例 1:列表視圖基準測試

我們使用 Native、React Native 和 Flutter 在 Android 和 iOS 上實現了相同的用戶界面。我們還使用 RecyclerView 實現了滾動速度的自動化。在 Android 上我們使用 SmoothScroller;在 iOS 和 React Native 上,我們使用了一種定時器和以編程方式滾動到位置的方法;在 Flutter 上,我們使用 ScrollController 來平滑地滾動列表。在每種情況下,我們在列表視圖中都有 1000 個項目,並且都使用同樣的滾動時間才能到達最後一個列表元素。在每種情況下,我們在每個平臺上使用不同庫的圖像緩存。更多的細節可參閱 源代碼。

本案例使用的第三方庫:

iOS

加載和緩存圖像:Nuke

Android

加載和緩存圖像:Glide

React Native

加載和緩存圖像:React-native-fast-image

測試結果:

Android

GPU 測試結果不受基準測試的支持(不幸的是,這樣的設備我們還有很多)。

所有測試都顯示 FPS 大致相同。

與 Flutter 和 React Native 相比,Android Native 使用的內存只有一半。

React Native 需要最大程度的 CPU 利用率。原因是在 JS 和 Native 代碼之間使用 JSBridge,這會導致在序列化和反序列化上資源的浪費。

在電池開發方面,Android Native 取得了最好的結果。React Native 落後於 Android 和 Flutter。在 React Native 上運行連續動畫會消耗更多的電池電量。

iOS

FPS:React Native 的結果比 Flutter 和 Swift 更差。原因是無法在 iOS 上使用 IoT 編譯。

內存:Flutter 在內存消耗上方面基於與原生方式相當,但在 CPU 的佔用率仍然較高。在這項測試中,React Native 遠遠落後於 Flutter 和 Native。

Flutter 和 Swift 之間的區別:當 iOS Native 正在使用 GPU 時,Flutter 正在使用 CPU。Flutter 中的協調增加了 CPU 上的負載。

用例 2:重動畫測試

如今,大多數 Android 和 iOS 手機的硬件配置都很強大。在大多數情況下,使用普通應用,FPS 的下降並不會引人注意。這就是爲什麼我們決定用重動畫進行一些測試。這些動畫重到足以讓 FPS 下降到引人注意的地步。我們在 Android、iOS、React Native 上使用 Lottie 製作的矢量動畫,並在 Flutter 上的 Flare 採用了同樣的動畫。

使用 Android、iOS 和 React Native 版的 Lottie 和 Flutter 的 Flare 測試動畫。

Android 上的 Lottie

Android 測試結果

iOS 測試結果

Android

Android 和 React Native 在性能上表現相似,這是顯而易見的,因爲 React Native 版的 Lottie 使用了原生方式(CPU 佔用率 16~19%,FPS 爲 30~29)。

Flutter 的結果令人驚訝,儘管它在性能演示中有點搞砸了(CPU 佔用率爲 12%,FPS 爲 9)。

我們發現,從網格中刪除一個特定的動畫,會讓 Flutter 上的 FPS 最高提高 40%。我們認爲 Flare 更重,並且沒有針對這類任務進行優化,這就是爲什麼 Flutter 獲得如此高的 FPS 下降。

Android 需要的內存最少(205MB),React Native 需要 280MB,Flutter 需要 266MB。

應用程序冷啓動。Flutter 在這個指標上表現最好(2 秒),而 Android Native 和 React Native 大約需要 4 秒鐘。

iOS

iOS 和 React Native 在這個測試中的結果幾乎與 Lottie 的 React Native 使用原生方式相同。

Flare 和 Flutter 依然讓人驚訝,Flare 肯定還有一段路要走。

iOS Native 需要的內存最少(48MB),React Native 需要 135MB,Flutter 需要 117MB。

應用程序冷啓動。Flutter 在這個指標上表現最好(2 秒),而 iOS 和 React Native 大約需要 10 秒鐘。

請注意:在這個用例中,Flutter 用了一個不同的庫,與我們在其他平臺上使用的庫相比,這個庫要重得多,這可能是導致 FPS 下降的原因。

用例 3:旋轉、縮放和淡入淡出

在這項測試中,我們比較了 200 張動圖的動畫性能,縮放、旋轉和淡入淡出同時執行。

200 張動圖

Android 測試結果

Android

Native 顯示了最高的性能及最高效的內存消耗。

Flutter 顯示了非常接近 Native 的 FPS,內存開銷增加了兩倍多,但仍有不錯的性能。

React Native 在這種用例中表現不佳。

iOS 測試結果

iOS

iPhone 6S 足夠強大,在所有這 3 種用例中,FPS 都不會下降。

Native 佔用的資源較少,而 GPU 佔用率最多。

React Native 主要使用 CPU 進行渲染,而 Flutter 使用 GPU。

React Native 佔用了更多的內存。

總 結

對於一般的應用來說,小型動畫和炫酷的外觀,選擇哪種技術根本不重要。但如果要做一些重動畫的話,請記住,Native 具有最強的性能。其次就是 Flutter 和 React Native。我們絕對不推薦在 CPU 佔用率很高的操作中使用 React Native,而 Flutter 非常適合這種任務,無論是從 CPU 還是內存的角度。

選擇哪種工具要取決於具體的產品和業務案例。如果你想開發一個單一平臺 MVP——使用原生方式,但請記住,Flutter 應用程序可以同時爲移動、網絡和桌面環境而構建,而且我們有預感,Flutter 在不久的將來有望成爲跨平臺開發的王者,因爲即使在今天,Flutter 也是原生開發工具一個非常不錯的競爭對手,特別是如果你的開發預算不是太緊張,但你仍然想爲應用程序謀求良好性能的話。

我們面對的事實是,可能會有很多因素影響每個技術的實施和基準,而你們中的許多人,可能是某個特定平臺的真正專家,可以從心愛的工具集中獲取更多的好處。我們試圖通過爲每個應用創建一個單一的測試環境,以及一套單一的工具來衡量性能,從而將盡可能提高整個過程的透明度,我希望你喜歡我們這樣得到的結果。

相關文章