天天看點

我不認為Flutter比React Native好

作者|Jamon Holmgren

譯者|核子可樂

編輯|燕珊

Jamon Holmgren 是一家軟體開發公司的創始人兼 CTO,擁有超過 25 年的程式設計經驗,同時也是 React Native 的核心成員,維護着幾個開源庫。在這篇文章裡,他試着盡可能公平地從多方面去讨論 Flutter 和 React Native 的優劣勢。本文僅代表他個人觀點,希望能為讀者帶來收獲。

作為目前人氣最高的多平台移動應用架構,Flutter 與 React Native 可謂難分伯仲。關于二者誰更勝一籌的争議也從未止歇……開發者紛紛站隊,應用傳遞也隻選其一。那麼,到底誰更強?

取巧的回答是,“具體要分情況。二者各有利弊,選誰不選誰、要看具體取舍。”

但這樣的回答說了等于沒說。廢話文學解決不了問題,正面對線才是群衆們喜聞樂見的場面。是以,咱們就整點直接的、刺激的,聊聊 Flutter 和 React Native 誰更強。

1

這話題,重要嗎?

其實不重要,但不重要不代表沒意思:性能、開發者體驗、Dart 與 JavaScript、本機內建、标準庫等等都是很有意思的話題,都值得拿來一聊。

有些朋友可能覺得這篇文章有點标題黨,别着急,我會在後文中以更細微的方式深入探讨論斷背後的種種細節。

現在咱們直入正題:這話題,重要嗎?

說重要也重要,對于一家打算開發新應用的企業來說,以下幾個問題就是無法回避的現實考量:

招聘

現在,招聘開發者可謂困難重重。技術崗位的工資不斷上漲,市場供應卻相當有限。想來的人看不上、看上的人不想來,難得很。

Flutter 開發者的群體特征,可以用熱情和優秀來概括,也展現出整個技術社群的整體傾向。但問題是,這類開發者數量不大,沒法像 Dart 那樣随招随有。是以,我們隻能在企業内部不斷教育訓練,引導大家掌握 Flutter。

另一方面,React Native 開發者的規模就相當可觀了,背靠的是聲名極盛的 JavaScript 社群。JavaScript(及其變體 TypeScript)堪稱目前世界上最為流行的程式設計語言,而且參與者數量仍在快速增長。支援 React Native 的 React.js 也可以說是世界上最大的編碼架構之一,甚至沒有之一。是以,招聘工作雖然也是困難重重,但可供選擇的開發者數量肯定比 Flutter 大得多。另外,React 開發者也能比較輕松地轉型成高效靠譜的 React Native 開發者。

共享代碼、知識與開發者

除了招聘之外,決定 Flutter 和 React Native 誰更強的另一個重要因素,就是共享代碼、知識與開發者的規模。

在軟體開發領域,有什麼是比代碼好更重要的?那就是代碼少。而削減代碼工作量的最佳方式之一,就是在各種應用程式之間共享現有代碼成果。這不僅能縮短初始開發周期,也有利于簡化長期維護流程。

沒準你的公司正在網站、Web 應用程式或者伺服器當中使用 React.js,或者至少在用 JavaScript。這種在 React.js 應用程式、Node 伺服器等場景之間共享代碼的能力,正是 React Native 最引以為傲的資本——相比之下,Flutter 就明顯弱一些。

除了共享代碼,React Native 還能在 Web、後端、iOS 及 Android 團隊之間實作知識共享。網上關于 React Native、React 和 JavaScript 的教程也是所在多有,這還沒算上技術博文、StackOverflow 問答等補充性内容。

另外,開發者也能在各個項目之間“反複橫跳”,不用經過多少二次教育訓練就能快速投身于時間緊、任務重的關鍵項目。

是以在 React Native 和 Flutter 二選一的交鋒中,我們很難忽略上面這些基本事實。

2

那,其他因素呢?

是的,性能、開發者體驗、可通路性、第三方庫生态也都很重要。

而在這些方面,Flutter 與 React Native 基本是拼了個五五開。Flutter 在某些方面勝出,React Native 也擁有自己的特定優勢。是以除了能跟 Web 共享代碼這一條外,二者在其他特定方面都屬于勢均力敵的狀态。

開發者體驗

Flutter 團隊(乃至整個 Google)真的很擅長設計開發者體驗。

Flutter 的開發環境設定難度一般低于 React Native。Flutter 的熱重載效果也比 React Native 的快速重新整理好一些。它提供非常出色的部件調試、分析與檢查工具,内置的端到端測試功能也比 React Native 的 Detox 好很多。Flutter 的 CLI 堪稱行業頂尖——我就特别喜歡其中的 flutter doctor 指令,允許開發者直接通過 CLI 管理自己的模拟器與仿真器。

Flutter 的更新體驗也更好,我們直接在現有應用程式中運作 flutter create,它就能根據新版本重建所有内容。

與之相比,React Native 的很多工具不像 Flutter 那樣優雅完善。其中最讓人難受的就是更新體驗,最近幾年用過 React Native 的朋友們應該對此深有同感。

當然,情況也在逐漸改善。微軟的幾位大佬就在之前的訪談中讨論過 React Native 工具與開發者體驗的改進思路。

此外,Expo 也确實極大改善了 React Native 中的開發者體驗。使用 Expo 服務,大家不僅能夠實作原版 React Native 中的一切功能,還将獲得更好的更新體驗與內建工具運作效果。如果不打算使用自定義本機代碼,Expo Go 則是一種無需編譯即可與他人快速共享 build 的絕佳方式。總之,如果你正在使用 React Native,千萬别跟 Expo 失之交臂!

小總結:Flutter 的開發者體驗具有明顯優勢;React Native 雖然正在迎頭趕上,但還有很長的路要走——不過 Expo 的出現帶來了一股強勁助力。

性能

軟體架構的性能差異其實很難比較,更不用說像 Flutter 和 React Native 這樣高度複雜的架構方案了。在大多數情況下,Flutter 和 React Native 的速度都“夠快”,如果開發者有能力做一點性能優化,那運作效果更是毫無問題。

不過從曆史上看,Flutter 的開箱即用性能一直要優于 React Native。當然,防杠聲明:我們都見過性能極差的 Flutter 應用程式和性能極佳的 React Native 應用程式,這裡說的隻是整體趨勢。

二者的性能差異,主要源自異步 React Native 橋接器。但随着今年春季新架構的推出,它将被原生與 JS 代碼間的并發通信所取代。此外,Hermes JS 引擎也讓許多關鍵性能名額更上一層樓。最後,Skia 現已加入 React Native 全家桶,意味着大家可以在 React Native 用到跟 Flutter 相同的渲染器了——當然,僅限于需要流暢性能的位置。

小總結:Flutter 在性能方面暫時小幅領先,但 React Native 新架構的推出有望快速縮小這方面差距。

統一的 UI 體驗

Flutter 使用 Skia 進行 UI 渲染,而且在所有平台上都提供統一的外觀。這樣開發者就能優化性能、自定義 UI,有效擺脫平台天然特性的影響。

另一方面,React Native 在 iOS 上使用 UIKit,在 Android 上使用 Android 布局系統,在 Web 上用的則是 DOM。這意味着雖然我們在建構應用程式外觀時可以盡量強調相似,但實際跑在不同平台上時往往受到具體解釋方法的影響。

人們對 Flutter 一直有怨言,批評它總在重新發明已經由平台自身解決了的各種問題,包括輔助功能、字型縮放等等。公平地講,Flutter 的方案效果不錯(使用較低層級的内置平台 hook),但畢竟是費了二遍勁;相比之下,React Native 就總能或多或少依賴于平台提供的原語。

另外值得一提的是,Google 開發者曾經表示不再将統一體驗作為核心目标。這似乎跟 Flutter 的路線不太比對。

小總結:如果大家覺得在不同平台上更好地比對使用者體驗、要比提供跨平台統一體驗更重要,那麼 React Native 還是略微勝出。

原生內建

Flutter 會把 Dart 代碼編譯成原生代碼,再使用自身所謂平台通道(Platform Channels)将原生代碼納入酷炫的內建模型。它允許同步本機調用,也允許開發者使用 Swift 和 Kotlin 編寫代碼。Flutter 的說明文檔品質也很高,并提供開箱即用的測試與模拟等多種工具。無論你選擇哪種平台,這裡都提供大量模闆,并通過 Isolates 實作了一流的線程支援功能。

而在 React Native 這邊,原生內建就有一定的入門門檻了。另外,我們還得跟 React Native 橋接局限作鬥争,原生內建的說明文檔也不盡人意。

值得注意的是,新一代 React Native 架構直接去年了橋接器,全面引入了原生同步內建優勢。是以更新之後,React Native 的缺點已經不多了。

小總結:兩大平台都具備完整的原生內建能力,但 Flutter 的原生內建工具更好些。

國際化水準

國際化 / 本地化(i18n)當然重要。Flutter 就内置有 i18n 支援,是以不依賴于其他第三方。而 React Native 雖然缺少内置支援,但其中的第三方 i18n 支援确實越來越好。

小總結:沒有輸赢——兩大平台在國際化方面都表現不錯,但也各自存在一些局限。

内置導航(及更多)

Flutter 在設計上比 React Native 更貼心,最典型的展現就是它帶有自己的導航 / 路由解決方案。

導航屬于特别适合內建到核心架構中的子產品,因為它對大多數應用程式來說非常重要。大家可以想象一下不帶路由程式的 Next.js……那就基本廢了。

React Native 走的則是更為靈活的路線,允許開發者随意引入自己熟悉的導航解決方案。選項很多,但支援效果最好的是 React Navigation 和 React Native Navigation 庫(有點遺憾)。

Flutter 還提供内置的主題支援等功能。另一方面,作為 React Native 上的樣闆選項,Ignite 也有自己的主題支援功能,唯一的差別就是這些主題并非 React Native 的内置主題。

Flutter 這種内置路線的好處,開發者可以随意調整相應功能以比對各個版本的架構特性。但内置路線也有缺點,就是一旦出現更好的範式,開發者隻能祈禱官方支援團隊能盡快更換那些更新、更好的解決方案。

小總結:Flutter 有一定優勢。帶内置導航子產品肯定不是壞事,不過 React Native 社群也提供不少出色選項。

Web 支援

Flutter 2 宣布将支援 Web 及其他平台。

但他們選擇的 Web 方法隻能說是“允許開發者在畫布上繪制”,而非使用原生 DOM。

這肯定會帶來輔助功能和 SEO 方面的問題。還不止如此……總之,委婉一點講,用 Flutter 開發 Web 應用程式應該不是首選方案。

值得一提的是,Flutter 确實也提供 HTML/CSS/DOM 版本,隻是用得沒畫布渲染器多。但即使如此,在這方面它也根本無法與 React.js 相抗衡。

另一方面,無論大家是用 React Native 開發 Web 應用程式、還是直接選擇 React.js,React Native 都能直接共享代碼。通過 JavaScript/Typescript 共享服務與子產品,開發者能夠輕松共享大量業務邏輯、資料模型等,并在 Web 應用程式中拆分并直接共享 UI 元件。總之,React.js 是專為 Web 而生,一切設計都以 Web 開發為目标,這一點跟 Flutter for Web 有所不同。

小總結:React Native 占據明顯優勢。雖然 Flutter 2 也在朝着這個方向邁進,但 React Native 在 Web 領域已經擁有巨大的先發優勢。想要縮小差距,很難的啦。

第三方庫

在典型的 React Native 應用當中,我們會用到大量最初專為 JavaScript 或 React 設計的庫和工具,包括 axios, mobx, redux, lodash, ramda, eslint, babel, jest, prettier, react-devtools, typescript, npm 以及 yarn 等等。

這些都是 Web 和 Node 開發者常用的庫。是以在社群合并之後,這些工具将獲得兩方面的貢獻和改進,知識共享與互幫互助的氛圍也更好。

另一方面,Flutter 則主要使用量身定制的庫。雖然市面上也有部分第三方 Dart 庫可用,但社群規模遠遠不及 JavaScript。

話雖如此,但 Dart 其實帶有統一的格式化程式、測試、編譯器、分析器 /linter 與包管理器,同時也是一種類型安全與空值安全的語言。是以在使用 Flutter 加 Dart 時,開發者可能很少需要再借助什麼第三方庫。

小總結:Flutter 與 Dart 都提供不少高品質的内置工具,但 React Native 擁有顯著的第三方生态規模優勢。而且必須承認,Dart/Flutter 這樣的孤立社群基本不可能重制 JavaScript/React 這樣的強大生态系統。

使用 React Native 與 Flutter 的公司

React Native 的發展壯大離不開衆多企業的不懈努力。除了 Meta/Facebook 之外,微軟也在大力投資 React Native 項目開發。項目核心團隊一直與微軟開發者在各個方面上開展合作,微軟一方還使用 React Native 重寫了許多應用程式,并為其建構了大量工具和庫。事實上,微軟最近甚至宣布連 Windows 中的主 Settings 應用就有一部分是用 React Native 編寫的!

除了 Meta(Facebook 與 Instagram)和微軟之外,React Native 還得到了 Coinbase, Shopify, Mercari, Discord, Pinterest, 特斯拉, 沃爾瑪, Wix, Salesforce, NFL, MLS 以及 Uber Eats 等大型組織機構的廣泛使用。

Flutter 的支援力量主要來自 Google,而縱觀整個發展曆程,Google 對項目的支援表現隻能說是喜憂參半。另有一些企業也在使用 Flutter,包括豐田、eBay 與阿裡巴巴,但大部分開發工作還是由 Google 親自推動。

話雖如此,但 Flutter 在開放性、全面開源、社群的持續參與以及回報驅動開發方面做得很好。與之對應,React Native 給人的感覺就有點以自我為中心,一般優先考慮 Meta/Facebook 的實際需求,之後再把成果推向外部。但 React Native 核心團隊一直在努力讓項目轉向社群驅動。

小總結:React Native 占優勢。這個問題比較複雜,涉及很多細小差别,這裡就不過多贅述了。

動态更新(代碼推送等)

很多項目其實并不需要動态更新,但不少企業客戶倒是因為這個喜歡上了 React Native,因為它能對應用程式進行動态更新、進而避過 App Store 和 Play Store 複雜的審批流程。Flutter 這邊就沒有類似的設計,在未來發展路線圖上也沒提到。

小總結:優勢在 React Native。

3

是以,我們到底該用 React Native 還是 Flutter?

具體要分情況。二者各有利弊,選誰不選誰、要看具體取舍……雖然網上關于這個問題總是吵得沸沸揚揚,但還就真沒個确切的答案、二者的差異也着實不太明顯。

前文已經提到,市場上的技術人才儲備直接決定着招聘難度,這可能是具體選擇時的首要考量因素。如果你已經擁有使用 JavaScript/TypeScript 的 Web 及後端開發人才,特别是已經在使用 React,那麼 React Native 肯定是更好的答案。

如果你站的是 Java 或者 Android 這隊(掌握 Java/Kotlin 的開發者可以輕松上手 Dart),而且 / 或者需要更統一、更流暢的 UI,那 Flutter 的優勢就展現出來了。雖然招聘難度也許更高,但 Flutter 至少還提供更好的開發者體驗與性能表現。

總之,在抛開了“正确的廢話”之後,現在大家又多了一點指導權衡思考的素材。

4

寫在最後

這個話題着實敏感,稍不注意就要挨罵,是以我得再說幾句免責聲明。首先,這隻是我的個人觀點。我做的就是 React Native 咨詢業務、而且與 React Native 核心團隊保持合作,是以我不會說自己的觀點有多麼客觀公正。但我确實做了不少研究,充分考慮到兩大平台的業務合作現狀,也在撰稿時參考了幾位 Flutter 開發者的修改意見。他們也許不同意我的觀點和結論,但我确實有認真考量他們的回報資訊。總之,我希望盡可能在文章中公平讨論這個問題。

我也不關注那些什麼美學、優雅層面的問題,例如 Dart 和 TypeScript 的文法、或者 JSX 和 Dart 的功能部件結構誰更好之類。這些屬于個人喜好問題,争來争去也不會有确切的結論,也不至于給架構的可用性帶來任何本質影響。Dart 和 JavaScript/TypeScript 之間當然有差別,但這又是另一個話題,不在本文的讨論範圍内了。

最後,對本文觀點持贊同或不同意見的讀者,都不妨在留言中聊聊自己的看法。

繼續閱讀