導語 | Flutter 框架是當下非常熱門的跨端解決方案,能夠幫助開發者通過一套程式碼庫高效構建多平臺精美應用,支援移動、Web、桌面等多端開發。但仍然有很多產品、設計、甚至開發同學並不瞭解 Flutter,所以本文將深入淺出和大家聊聊 Flutter 的設計背景、技術特點,以及與其他同類技術之間的對比,希望與大家一同交流。
一、跨平臺背景
1. 移動網際網路的重要性
如上圖所示,與2019年1月相比,全球使用網際網路的人數已增加到45.4億,增長了7%(2.98億新使用者)。
到2020年1月,全球有38億社交媒體使用者,與去年同期相比,這個數字增長了9%以上(3.21億新使用者)。
在全球範圍內,現在有超過51.9億人使用手機,在過去的一年中,使用者數量增加了1.24億(2.4%)。
現在,普通的網際網路使用者每天線上花費6個小時43分鐘,相當於每個網際網路使用者每年連線時間超過100天。如果我們每天需要大約8小時的睡眠,那就意味著醒來的時間中,有40%以上是通過網際網路度過的。
在移動網際網路的浪潮下,開發效率和使用體驗可以說是同等重要。但是,使用原生的方式來開發 App,就要求我們必須針對 iOS 和 Android 這兩個平臺分別開發。
這樣就導致了我們不僅需要在不同的專案間嘗試用不同的語言去實現同樣的功能,還要承擔由此帶來的維護任務。如果還要繼續向其他平臺(比如 Web、Mac 或 Windows)擴充的話,需要付出的時間和成本將成倍增長。而這,顯然是難以接受的。於是,跨平臺開發的概念順勢走進了大家的視野。
從本質上講,跨平臺開發是為了增加業務程式碼的複用率,減少因為要適配多個平臺帶來的工作量,從而降低開發成本。
2. 跨平臺開發方案的三個時代
根據實現方式的不同,業內常見的觀點是將主流的跨平臺方案劃分為三個時代。
(1)Web 容器時代
基於 Web 相關技術通過瀏覽器元件來實現介面及功能,典型的框架包括 Cordova(PhoneGap)、Ionic 和微信小程式。
Web 時代的方案,主要採用的是原生應用內嵌瀏覽器控制元件 WebView 的方式進行 HTML5 頁面渲染。
由於採用了 Web 開發技術,社群和資源非常豐富,開發效率也很高。但是,一個完整 HTML5 頁面的展示要經歷瀏覽器控制元件的載入、解析和渲染三大過程,效能消耗要比原生開發增加 N 個數量級。
(2)泛 Web 容器時代
採用類 Web 標準進行開發,但在執行時把繪製和渲染交由原生系統接管的技術,代表框架有 React Native、Weex 和快應用,廣義的還包括天貓的 Virtual View 等。
泛 Web 容器時代的解決方案優化了 Web 容器時代的載入、解析和渲染這三大過程,把影響它們獨立執行的 Web 標準進行了裁剪,以相對簡單的方式支援了構建移動端頁面必要的 Web 標準(如 Flexbox 等),也保證了便捷的前端開發體驗。
同時,採用原生自帶的 UI 元件實現代替了核心的渲染引擎,僅保持必要的基本控制元件渲染能力,從而使得渲染過程更加簡化,也保證了良好的渲染效能。
也就是說,在泛 Web 容器時代,我們仍然採用前端友好的 JavaScript 進行開發,整體載入、渲染機制大大簡化,並且由原生接管繪製,即將原生系統作為渲染的後端,為依託於 JavaScript 虛擬機器的 JavaScript 程式碼提供所需要的 UI 控制元件的實體。
這也是現在絕大部分跨平臺框架的思路,而 React Native 和 Weex 就是其中的佼佼者。總結起來其實就是利用 JS 來呼叫 Native 端的元件,從而實現相應的功能。
(3)自繪引擎時代
自帶渲染引擎,客戶端僅提供一塊畫布即可獲得從業務邏輯到功能呈現的多端高度一致的渲染體驗。Flutter,是為數不多的代表。
這一時期的代表 Flutter 開闢了一種全新的思路,即從頭到尾重寫一套跨平臺的 UI 框架,包括渲染邏輯,甚至是開發語言。
渲染引擎依靠跨平臺的 Skia 圖形庫來實現,Skia 引擎會將使用 Dart 構建的抽象的檢視結構資料加工成 GPU 資料,交由 OpenGL 最終提供給 GPU 渲染,至此完成渲染閉環,因此可以在最大程度上保證一款應用在不同平臺、不同裝置上的體驗一致性。
而開發語言選用的是同時支援 JIT(Just-in-Time,即時編譯)和 AOT(Ahead-of-Time,預編譯)的 Dart,不僅保證了開發效率,更提升了執行效率(比使用 JavaScript 開發的泛 Web 容器方案要高得多)。
二、Flutter 的前世今生
1. Flutter 出現的歷史背景
為不同的作業系統開發擁有相同功能的應用程式,開發人員只有兩個選擇:
-
使用原生開發語言(即 Java 和 Objective-C),針對不同平臺分別進行開發;
-
使用跨平臺解決方案,對不同平臺進行統一開發。
原生開發方式的體驗最好,但研發效率和研發成本相對較高;而跨平臺開發方式研發雖然效率高,但為了抹平多端平臺差異,各類解決方案暴露的元件和 API 較原生開發相比少很多,因此研發體驗和產品功能並不完美。
所以,最成功的跨平臺開發方案其實是依託於瀏覽器控制元件的 Web。瀏覽器保證了 99% 的概率下 Web 的需求都是可以實現的,不需要業務“將就”技術。
不過,Web 最大的問題在於它的效能和體驗與原生開發存在肉眼可感知的差異,因此並不適用於對體驗要求較高的場景。
對於使用者體驗更接近於原生的 React Native,對業務的支援能力卻還不到瀏覽器的 5%,僅適用於中低複雜度的低互動類頁面。面對稍微複雜一點兒的互動和動畫需求,開發者都需要 case by case 地去 review,甚至還可能要通過原生程式碼去擴充套件才能實現。
帶著這些問題,我們終於迎來了本次的主角——Flutter。
Flutter 是構建 Google 物聯網作業系統 Fuchsia 的 SDK,主打跨平臺、高保真、高效能。開發者可以通過 Dart 語言開發 App,一套程式碼可以同時執行在 iOS 和 Android 平臺。Flutter 使用 Native 引擎渲染檢視,並提供了豐富的元件和介面,這無疑為開發者和使用者都提供了良好的體驗。
那麼,Flutter 是怎麼完成元件渲染的呢?
這需要從影像顯示的基本原理說起。在計算機系統中,影像的顯示需要 CPU、GPU 和顯示器一起配合完成:CPU 負責影像資料計算,GPU 負責影像資料渲染,而顯示器則負責最終影像顯示。
隨後視訊控制器會以每秒 60 次的速度,從幀緩衝區讀取幀資料交由顯示器完成影像顯示。
可以看到,Flutter 關注如何儘可能快地在兩個硬體時鐘的 VSync 訊號之間計算併合成檢視資料,然後通過 Skia 交給 GPU 渲染:UI 執行緒使用 Dart 來構建檢視結構資料,這些資料會在 GPU 執行緒進行圖層合成,隨後交給 Skia 引擎加工成 GPU 資料,而這些資料會通過 OpenGL 最終提供給 GPU 渲染。
2. 關於Skia
Skia是一個開源的 2D 圖形庫,提供各種常用的API,並可在多種軟硬體平臺上執行。谷歌Chrome瀏覽器、Chrome OS、安卓、Flutter、火狐瀏覽器、火狐作業系統以及其它許多產品都使用它作為圖形引擎。
Skia 在圖形轉換、文字渲染、點陣圖渲染方面都表現卓越,並提供了開發者友好的 API。
因此,架構於 Skia 之上的 Flutter,也因此擁有了徹底的跨平臺渲染能力。通過與 Skia 的深度定製及優化,Flutter 可以最大限度地抹平平臺差異,提高渲染效率與效能。
底層渲染能力統一了,上層開發介面和功能體驗也就隨即統一了,開發者再也不用操心平臺相關的渲染特性了。也就是說,Skia 保證了同一套程式碼呼叫在 Android 和 iOS 平臺上的渲染效果是完全一致的。
同樣的在介面渲染、繪製的過程中,Flutter也做了很多優化處理,提升合成、渲染效率。
3. FLutter的優勢
(1)在所有的平臺下,都可以保持同樣UI樣式,同樣的業務邏輯
大多數跨平臺框架中的UI呈現如下圖所示:
而Flutter是直接畫在畫布上:
(2)減少開發所需的時間
-
Flutter的熱過載可以高效快速的看到改變,甚至保留應用狀態;
-
官方提供的各種現成的元件(Material和Cupertino)。
(3)快速迭代上線
不需要單獨適配 iOS、Android 雙端的 UI 層面。
(4)更接近native的效能表現
Flutter不依賴任何中間程式碼,最終直接構建成機器碼,提高了效能。
(5)自定義複雜動畫
Flutter最大的優勢之一就是可以定製你在螢幕上看到的任何東西,不管它有多複雜。
(6)有自己的渲染引擎
Flutter使用Skia將介面渲染到平臺提供的畫布上,意味著不需調整,即可遷移到其他平臺。
(7)更方便呼叫native api
獲取GPS座標、藍芽通訊、收集感測器資料、許可權處理等,未支援的也可通過platform channel 。
(8)更高的潛力
iOS、Android、Web、Desktop…
三、Flutter 與 React Native (Hippy)
1. UI方面
在新舊裝置上也能保持一致
android 5.1
android 8.1
Flutter動畫效果:
2. 效能方面
基於 ListView ,我們做了一個基準測試。在 ListView 中,有1000個元素,並且到達列表最後一個元素的滾動時間相同,這裡使用到了一些第三方庫:
-
ios Nuke
-
Android Glide
-
react native React-native-fast-image
結果展示:
3. Flutter缺點
-
開發者社群的規模和第三方庫
-
持續整合的能力
-
APK的大小
-
Dart語言學習成本
-
動態更新能力
Q&A
Q:Flutter 和 Hippy 有什麼區別,為什麼用 Flutter,不用 Hippy?
A: 第一,Flutter開發效率高,可減少客戶端開發時間;第二,Flutter 在跨端UI差異小;第三,Flutter 動畫支援很全面;第四,它更接近native。
Q:Flutter 和 Hippy 在方案選型上有一些差異,比如自定義 UI 元件效能方面有哪些差異,介面怎麼通訊?
A:Flutter 自定義 UI 元件 platformview 的效能還有待提升,介面通訊方面,Hippy 與客戶端通過 jsbridge,而 Futter 是通過 methodchannel 。
Q:Flutter 為什麼暫時還不支援動態更新?
A:初期考慮到應用安全和蘋果方面的策略,所以不支援動態更新。現在 Android 端可以通過整包方式實現動態更新, iOS 目前還不支援。