從 React Native 到 Flutter,移動跨平臺方案的真相

作者:LeanCloud 鄭鵬

2018 年 12 月,Google 發佈了 Flutter 1.0 正式版,似乎再次點燃了人們對移動跨平臺開發的熱情。上一次出現類似的情況,是在 15 年年初,Facebook 發佈 React Native 的時候。四年不到的時間裏,有兩家大公司相繼推出了自己的移動跨平臺方案(當然還有 16 年的時候,微軟收購了 Xamarin,不過沒有前兩個那麼引人注目罷了),同時這些方案也受到了市場的追逐。這些現象,似乎預示着,跨平臺開發纔是移動開發的未來,或者說,跨平臺開發纔是一種更好的開發方式。

既然它是熱點,那肯定有可以討論的地方。不過,在說 React Native 和 Flutter 之前,我覺得要先談一談「跨平臺開發」。

移動跨平臺方案

那什麼是「跨平臺開發」呢?

通常意義上來說,如果你想在 iOS 以及 Android 系統裏,提供有相同內容的 App,那麼使用 Apple 提供的構建工具,開發一個 App,然後上架到 AppStore,同時使用 Google 提供的構建工具,開發一個 App,然後上架到 Google Play。這兩個 App 的實現,除了使用的工具不同之外,大部分業務邏輯是相同的。你可以發現,在這個過程中,產生了「重複」。

在重構時,如果項目裏有大量的重複代碼,或者重複邏輯,我們一般會將這些代碼或邏輯以函數,模塊或庫的形式做封裝,這個過程最大化的消除了重複的代碼,最終達到簡化項目的代碼這一目的。

所以在我看來,「跨平臺開發」也是基於這個思想而產生的,人們想要一套減少甚至不用寫重複邏輯的解決方案,然後市場給予了人們期望的方案。跨平臺方案的最大特點,可以用 Sun 當年在推廣 Java 時,所使用的一句口號:”Write once, run anywhere” 作爲總結。這一句話,也被如今的 React Native 以及 Flutter 引用或繼承。

React Native

React Native 是由 Facebook 所主導的跨平臺方案,得益於 Javascript 以及 ReactJS 的流行,React Native 在推出時,便受到了大量的追捧。除了跨平臺的特性,React Native 最大的特點就是,可以使用 Javascript 來構建移動應用,並且最終應用的表現形式,可以做到和使用原生開發套件開發的應用相差無幾。

React Native 能做到這些的核心原理就是 JavaScriptCore,一個 JavaScript 虛擬機。通過 JavaScriptCore,Javascript 能和其它語言互相轉義,同時 JavaScriptCore 能運行在 iOS,Android 以及其它平臺上,這些可能性放在一起,就成爲了 React Native 的基底。有了這個基底之後,Facebook 便在這個基礎之上,封裝了各平臺的應用層接口,定義了 Javascript 和封裝後的接口之間的通信協議,最終,實現了使用 JavaScript 在不同平臺開發具有原生體驗的應用。

從實現原理以及架構上來看,React Native 似乎是一個不錯的跨平臺方案,只要封裝好各平臺的 API,那麼我們有理由去相信,人們能夠使用 React Native 開發出品質優秀的應用。但是事實上,理想和現實,還是有差距的。在 18 年,AirBnB 以及 Udacity 相繼發表了博文,聲明全面放棄 React Native,轉向原生應用的開發。他們在文章中,提到的最多的就是,React Native 是一個不成熟的方案,雖然它有許許多多的優點,但是這些並不足以去彌補它的缺點帶來的損失。AirBnB 以及 Udacity 可能是因爲各種預期的理由而放棄了 React Native,不過在我看到 Discord 團隊發表的 Why Discord is Sticking with React Native 博文後,算是徹底打消了我在生產環境使用 React Native 的念頭。整篇文章看下來,讓 Discord 團隊仍然繼續使用 React Native 的最大原因,似乎就是項目已經使用了它,騎虎難下了。

JavaScriptCore 的侷限性,Facebook 在項目管理上的不成熟,以及不斷出現的放棄聲明,最終讓人們發現,React Native 是一個有趣的方案,但並不是一個成熟穩定的方案。

Flutter

就在 React Native 的人氣不斷下跌的時候,Google 在一個恰到好處的時機,推出了一套跨平臺方案:Flutter,將人們的目光再次聚集到跨平臺開發上面。

Flutter 使用 Dart 這門較爲冷門的語言來做開發,底基引擎主要由 Skia 和 Dart runtime 構成。Flutter 通過 Skia 和各平臺的底層圖形庫對接,同時提供豐富的基於 Skia 的控件,來實現跨平臺的開發。React Native 採用的方式是封裝各個平臺的應用層接口,而 Flutter 則直接打造了一套跨平臺的應用層的開發套件。對這兩種不同的方式,我們可以有一個直覺上的判斷,Flutter 在性能上是要優於 React Native 的。因爲 Flutter 的這種實現方式,其實早已被大量並廣泛的使用了,最明顯的例子就是遊戲引擎。

種種對比和跡象表明,似乎 Flutter 是一個比 React Native 更好的跨平臺方案。目前 Flutter 仍舊處於一個上升的勢頭,也有如阿里巴巴這種大廠給 Flutter 背書,頗具野心的底基框架讓開發者有理由相信,只要投入足夠的人力,Flutter 可以做到和原生開發一樣好。

然而,Flutter 的缺點,也是源於它自行打造了框架,在很多平臺特性上,諸如密碼管理,選擇光標等,Flutter 目前並不能支持,未來能否支持也要打上大大的問號,平臺的特性可能和原生組件深度綁定,且目前沒有其它接口,所以 Flutter 在現在這種狀態下,只能是放棄這些特性的支持。需要提一點的是,React Native 在這方面沒有太大的問題。

儘管有一些問題,不過 Flutter 表現出的潛力,還是讓人們覺得,這是一個值得一試的方案,只要 Google 給予足夠的支持。所以 Google 會嗎?

結語

那麼,我該選擇哪種方案呢?答案:It depends on you.

事實上就是,沒有一個完美的方案,任何方案都有利弊和取捨。想使用 Javascript 開發應用,那麼就使用 React Native;想構建高性能的跨平臺應用,Flutter 是個不錯的選擇;想最大化平臺特性,那自然是原生的開發方式。

除了跨平臺方案之間的比較之外,跨平臺方案也在和原生開發方式競爭,而且這種競爭往往是不平等的,跨平臺方案在新特性的支持上,始終要慢於原生開發方式,所以在市場佔有率方面,原生開發方式就有天然的先發優勢,這種差距很難被抹平。最終,你可能會發現,也許原生開發方式纔是最合適的,因爲除了「重複」外,原生開發方式相比跨平臺方案,沒有其它缺點了。

附記:之前我在 2019 年 3 月的 RTC Dev Meetup 北京站交流過上面的想法,感興趣的讀者可以查看演講視頻和 slide。

題圖:Chris Sabor

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章