1. 程式人生 > >譯文 | Flutter: the good, the bad and the ugly

譯文 | Flutter: the good, the bad and the ugly


去年這個時候,我發表了一篇文章,內容是我對 React Native 的印象,它在 2016 年和 2017 年風靡一時,Facebook,Instagram,Tesla,Walmart,Airbnb,Skype 等公司開始調研使用,並推出基於 RN 的業務的應用或在應用中部分頁面使用 RN。

但是今年,React Native 似乎正在失去它的市場吸引力,一些著名的公司已經宣佈放棄它(比如 Airbnb 和 Udacity)。 通過與開發人員交流中,釋出的文章中,或者在 LinkedIn 上招聘 JD進行判斷,看起來它不再那麼火爆了。 但要明確的是,它並沒有被遺棄,只是相對來說它對一些公司來說由於不適合而不在被使用,但是並不意味著它不適用於其他公司。 許多這些公司在其應用程式的子頁面而不是所有應用程式的子頁面上使用它,可能使用它如此複雜的原因之一。然而,我們不能否認,如果有助於推廣技術而做出貢獻的大公司(通過基於該技術建立的流行的開源庫)團隊一旦最終決定棄用它,它會對社群產生影響。但是這樣至少能幫助以前對使用它持觀望態度的團隊可以更容易地做出決定,使用上面這樣的例子來支援他們的是否投入。

2017 年有了些新的改變。 在 Google IO 開發者大會上,谷歌公開發布了自己的移動應用跨平臺技術早期 alpha 版本的 Flutter。 今年的會議中,谷歌宣佈 Flutter 已經準備好投入生產,並在已經在 9月底推出了 Release Preview 2。(譯者注:本週已釋出了 1.0 正式版)。官方提出了 Flutter 帶來的亮點:


1. 最新版本的主題是畫素完美的 iOS 應用程式(雖然以前主要集中的是 Android 的材質設計上)。

2. 注意,這款應用縮小了安裝包的大小,在釋出模式下,最小的 Android 應用現在只有4.7MB。

3. Flutter 從一開始就是開源的,它進入了 GitHub 上最活躍的 50 個 repo(倉庫) 中。

4. 一些大公司正在使用它,例如阿里巴巴(Android, iOS)、騰訊(Android, iOS)和谷歌廣告(Android, iOS)。阿里巴巴的閒魚就是基於 Flutter 開發的,並且在中國有5000多萬用戶在使用該應用。

5. 此圖表顯示了 Flutter 如何在Stack Overflow上獲得大量關注勢頭:


因此,這足夠激起了我的興趣去學習它,瞭解它的全部內容,並使用它建立一個真正的應用程式(因為,技術這種事僅靠閱讀文件是不足以獲得一些對新東西的真正掌握程度的)。

什麼是Flutter,它做了什麼?


1. Flutter 是由谷歌開發的一個開源軟體開發工具包(SDK),可以快速構建 iOS 端和 Android 端應用程式,兩個平臺共享大部分程式碼。它與 Android 和 iOS sdk 協同工作,這也意味著您仍然需要一臺 macOS 機器來為 iOS 構建(就像您為 React Native 和 Xamarin 所做的那樣)。

2. 它使用 Dart 程式語言構建程式,也是由 Google 開發的。 是的,需要學習一門新的語言,但不要擔心,如果你熟悉Java,JS,Kotlin,Swift 或 C#,這是非常容易的。

3. 該應用程式會提前編譯為本機 ARM 程式碼,而不是像 React Native 中那樣在執行時編譯。 這樣可以提供更好的效能,因為中間 沒有 JS bridge 來解析和執行程式碼。 但是,這也意味著通過在執行時下載新的 JS 程式碼包,沒有無線更新選項。

4. 它不是在 iOS / Android 特定的原生 UI 元件(這就是React Native和Xamarin所做的)之上的包裝器,而是通過一個 Skia

這個 C ++ 2D 圖形庫,快速的在「螢幕畫布」上從頭開始繪製UI。 Skia(也可作為谷歌 Chrome,Chrome OS,Android,Mozilla Firefox 和 Firefox OS 以及許多其他產品的圖形引擎)。Skia 專案開始於 1996 年,2005 年被谷歌收購,儘管它是在 BSD 許可下發布的,任何人都可以使用它。這將產生巨大的影響,我將在下面的利與弊部分詳細討論這個問題。

5. 與 React Native 類似,Flutter 也基於「單向資料流」架構或反應式程式設計。更簡單的是,應用程式通過更改變數或者屬性(或者更新螢幕或檢視的「狀態」)來響應使用者輸入,並根據新狀態重新渲染 UI。函式不會直接更改 UI (按鈕的顏色、標籤的文字、列表的內容等)。

6. 再次,與 React Native 類似,有熱更新。 您只需在程式碼編輯器中更改內容,儲存,並在 Android emu 或 iOS sim 上重新整理 UI。 這是非常方便和快速的,一旦你嘗試它就很難不去使用它,它彌補了 UI 是以程式設計方式建立的,因此沒有視覺化編輯器。

7. Flutter 可通過第三方外掛進行擴充套件,這些外掛可新增新的自定義 UI 元件或包含內建類尚未涵蓋的平臺特定功能(例如:用於視訊/音訊,貨幣化,儲存,相機,增強現實,機器學習等等)。

8. 與 7 相關聯,Flutter 通過在檢查 Platform.isIOS 和 Platform.isAndroid 之後執行不同的程式碼來編寫特定於平臺的程式碼變得相對容易(用於如果要在例項化的 UI 小部件中存在差異,或者 dart 檔案存在邏輯差異),或者通過編寫自己的原生外掛(如果你真的需要包含 Flutter 尚未提供的特定於平臺的功能)。

9. 依舊與 7 相關聯,效能應該不是典型應用程式的問題(至少在釋出模式下 - 除錯模式明顯更慢,因為它使用虛擬機器來執行 Dart 程式碼),因為 UI 是由快速低階寫入的 C++ lib 和其他功能對映到它們的原生部分。 但是,您必須通過最小化重繪次數並僅重繪狀態改變需要重繪的部分正確執行此操作。

10. 你可以使用任何文字編輯器和 flutter 命令來編寫和構建應用程式,但推薦的方法是使用支援 Flutter 外掛的編輯器之一,即 Android Studio,VS Code 或 Intelli J。這能給你更佳的程式設計體驗,您同時需要使用命令列來編譯和執行應用程式。

有什麼優點


1. Flutter 自己繪製 UI,而不是包裝特定於平臺的原生元件,這一事實既有優點也有缺點。優點是如果某樣東西在你的 iOS 12 測試 iPhone 上以某種方式呈現,那麼它以完全相同的方式呈現,不僅是在任何其他 iOS 版本上,而且在任何安卓手機上也是如此。而使用 React Native 或 Xamarin, UI 元件有許多屬性只在一個平臺或另一個平臺上受支援,或者它們雖然都支援,但在後臺以略微不同的方式被轉換為它們的本地對應元件。這意味著您需要在許多裝置和作業系統版本上進行測試(並且可能會編寫特定於平臺的程式碼來修復某些情況),或者只是知道某些使用者看起來可能會不同甚至影響功能。 如果您使用特定作業系統版本不支援的屬性或功能,您的應用甚至可能會崩潰。而使用 Flutter,您將更加安全(至少對於應用程式的 UI 部分是這樣)。 您仍需檢查多個裝置上的應用程式,尤其是在使用涉及到底層程式碼的第三方外掛時。 如果您使用音訊/視訊,推送通知,應用內結算等內容,就會出現這種情況。這種方法的消極方面將在本文的下一部分中介紹。

2. 熱更新非常有用,它完成了開發人員的夢想:編輯器中的儲存,以及應用程式在 SIM 卡上重新載入! 不用再去等待無盡的構建然後等待,執行然後等待再測試然後重啟的無盡的過程。 實際上,當您更改資源和外掛,更改導航中的某些內容,狀態初始化或邏輯時,仍需要重建,但大多數 UI 更改會在應用程式執行時立即應用。 對於 UI 複雜的應用程式,這是很浪費時間的地方。

3. 我喜歡小型可複用元件的整體遠離,它們會對「狀態」的變化作出反應來更新,這也是 React 和 React Native 的核心思想之一。 當然,反應型的應用程式也可以在純 iOS 和 Android 開發中開發,但使用 Flutter(和 RN )更容易,更自然。 這是因為它是核心,而不是由第三方庫提供並以多種不同方式實現的東西。

4. Dart 雖然簡單但是功能強大且完整,與 Swift,Kotlin 或 Java 相當。 使用 async / await / Future 進行非同步程式設計是輕而易舉的,它也感覺完整且一致。

5. Flutter 和 Dart 內建支援邏輯單元測試和 UI /互動的小部件測試。例如,您可以傳送點選和滾動手勢,在視窗小部件樹中查詢子視窗小部件,讀取文字,並驗證視窗小部件屬性的值是否正確。 官方文件很好地清楚地展示了可用的內容。

6. 我喜歡自帶的主題顏色支援的每一個方面的應用程式的 UI。在建立我的應用程式的明暗主題時,最困難的部分實際上是選擇正確的顏色(我只建立了兩種顏色,但用同樣的方法也可以建立10種)。就程式碼而言,它只有幾行。


優點:這是任何跨平臺技術在現實中都應具有的優勢,不僅僅是 Flutter,我還想提一下:為兩個平臺同時建立一個應用程式可以讓它們更容易保持一致。在傳統的開發過程中,您可能需要同時啟動這兩個平臺,並且具有相同的特性,但是不久之後您就會意識到一個平臺的效能優於另一個平臺(就下載、銷售、廣告收入而言)。然後你開始削減另一方面的成本,這意味著其中一個部分落後了。

不那麼好的部分


我不得不說我並沒有真正找到任何值得留在「壞」或「醜陋」部分的東西,但這裡有一些不太好的東西,至少從某些觀點來看:


1. 正如已經提到過的幾次,Flutter 以自己的自定義方式來繪製 UI,它不會使用原生元件。 它只是在複製 Android 的 Material Design 以及使用 Cupertino 庫的 iOS 特定元件方面表現非常出色,但它仍然不是原生的。 這有一些含義,例如:


(a) 如果 iOS 13 改變了分段控制元件或 UISwitch 的渲染方式,那麼使用 CupertinoSegmentedControl 或 CupertinoSwitch 的 Flutter 應用程式將保持舊的外觀,直到 Flutter 更新並重新構建程式。 有人可能會爭辯說很多使用者都不在乎(至少我的大多數非技術朋友都不關心,甚至不會注意到,例如,他們只關心應用程式看起來足夠漂亮而不是 100% 與作業系統的外觀和感覺一致),但如果你是一個強迫症或者追求純粹,它可能會會帶來不好的體驗。


(b) 如果您計劃僅將 Flutter 用於你現有應用程式的一部分,您可能會看到和原生部分之間存在差異和抖動的部分。同樣,這可能會困擾你(和你的使用者)。 但是對於 100% 的新應用程式來說,問題當然少了很多。


(c) 為了讓您作為開發人員覺得儘可能簡單,並假設您的使用者不關心應用程式的原生外觀,您可以使用 MaterialApp (使用Material Design元件)併為 Android 和 iOS 編譯它 。 它會工作正常,儘管非原生外觀,它實際上是我為我的應用程式做的。 相反,如果您確實關心這一點,並決定使用 MaterialApp for Android 和 CupertinoApp for iOS,那麼您將複製大部分(如果不是所有) UI 程式碼(這可能是您應用的相當一部分),並且你將使架構更復雜。 仔細考慮這一點並確定它是否值得。

2. Flutter 沒有像 React Native 甚至 Xamarin 那樣豐富的外掛。 這可能只是因為 Flutter 更新迭代,而且目前社群規模更小,但事實情況就是如此。 選擇是有限的,許多外掛都是舊的,沒有維護,甚至可能甚至不適用使用當前的 Dart / Flutter 版本。 一些元件(特別是非 UI 元件,對映特定於平臺的功能)僅適用於 iOS 或 Android,但不適用於兩者(通常它們支援Android,因為此時 Android 開發人員更多的是 Flutter 而不是 iOS 開發者,因為 Flutter 是來自谷歌的產物)。 然而,填補空白併為缺失的平臺編寫特定於平臺的程式碼仍然比從頭開始更好,並且如果 Flutter 越來越受歡迎,情況肯定會有所改善。


3. 除錯(debug)不是最好的。 您可以使用 print / debugPrint 語句,檢視日誌,並使用工具來分析 CPU /記憶體或視覺化檢視層次結構,但與使用 Xcode 或 Android Studio 中的操作相比,我們彷彿處於不同的星球上。但是您可以使用斷點,單步執行程式碼並檢查變數值,就像使用Java / Kotlin Android 一樣。這適用於 Android Studio 和 VSCode。

4. 當出現佈局錯誤(或其他較低級別的)時,您獲得的錯誤在螢幕或日誌可能會非常混亂和模糊,因為它指向框架的某些程式碼行,可能是您直接與下面的許多底層級別的互動。 在原生 iOS 和 Android 上,錯誤通常更容易理解,如果沒有,您通常只需在 Google 上覆制並貼上完整錯誤,並有理由相信您會獲得一個有用的連結列表,告訴您更多資訊。 但是對於 Flutter 來說,社群仍然相對較小,而不是那麼多的問題得到解答。

5. 以編碼方式(在螢幕程式碼所在的.dart檔案中)建立 UI 非常簡單直接。這也意味著沒有多少分離。 但我更喜歡在單獨的檔案中建立帶有標記程式碼的 UI(類似於在原生Android應用程式中執行的操作)。

6. 在 Android 上,絕大多數開發人員使用 Clean Architecture 和 MVP思想。 在 iOS 上,它可以是 MVC,MVVM Viper 等思想。 在這兩種情況下(但對於 Android 來說甚至更多),有明確且眾所周知的架構模式已被證明適用於大型應用程式。 但對於 Flutter (以及 React Native ),感覺它們仍然在初期探索的階段,沒有「標準」或「幾乎普遍接受」的架構方法。 所有文章都只是顯示簡單的例子,這是正常的,因為在談論更高階的方面之前,他們仍然需要去了解。 但是,如果您打算將 Flutter 用於相當大的專案前,那麼你最好清楚地瞭解如何構建它,以便隨著應用程式的大小和複雜性的逐漸增加,可以更好的擴充套件並且易於維護。同樣,我絕對不是說 Flutter 不允許你構建具有乾淨和可維護架構的應用程式,而只是會涉及一些調研和試錯的階段,因為它不是那麼成熟和廣泛使用的東西。正如我們在原生 iOS / Android 應用程式中習慣的那樣。

結論


總結一下:Flutter 有很多潛力,它很容易上手,實際上動手去做一些東西,並且有許多好的原則和想法。 然而,社群仍然很小,跨平臺外掛缺少積累,或者在當下的情況下沒有太多選擇。 此外,你必須接受沒有 100% 具有原生系統外觀的 UI 這一事實,如果你想要至少儘可能接近 iOS 和 Android,你的程式碼和結構將獲得更多複雜。


就個人而言,我認為這是一種非常有用的技術,適用於以下情況:

  • 您需要儘可能快地達到最廣泛的使用者群體 —— 例如,從頭開始就希望在 ios/Android 平臺釋出應用的初創公司。 看看是否有一個或兩個釋出需求,然後去考慮投入更多,取捨等等。你可以看到這是一個非常先進的原型,以後可以進一步看準需求選擇留在 Flutter 或由原生版本和專門團隊取代。
  • UI 無論如何都不是最大的問題 —— 例如對於企業/ B2B 應用程式,您只希望擁有一個業務線應用程式,員工/客戶可以使用這些應用程式在任何型別的裝置,但不太關心它是否一致與原生 OS 生態系統中的其他所有內容相關。


最後想說的是,建立我的第一個簡單的應用程式在大多數情況下非常愉快,儘管我過去開發了很多 iOS 和 Android 原生應用程式,但我確信它花了我更少的時間 在 Flutter 中建立一個應用(儘管我開始時並不瞭解它),而不是建立兩個獨立的原生應用程式。


原文連結:medium.com/asos-techbl…