讓我們在2019年重新認識 Flutter
現(xiàn)在是2019年,讓我們認真來看看備受矚目的 Flutter,重新認識一下它。本文首先簡要回顧移動開發(fā)(跨平臺開發(fā))的發(fā)展歷史,并談?wù)劜煌A段跨平臺解決方案的優(yōu)劣;接著從 WHAT / HOW / WHY 三個方面詳細來聊聊 Flutter,并結(jié)合簡單的 Dart 代碼說說開發(fā)者該如何上手,隨后展示幾個 Demo App;最后會就本次分享進行一段小結(jié)。Flutter 到底是什么,它的來臨對前端又意味著什么?讓我們接著往下看。
一、移動開發(fā)歷史回顧
當(dāng)下的移動互聯(lián)網(wǎng)仿佛給我們營造一種假象—— Android 和 iOS 已經(jīng)存在許多年。而回首過往,才發(fā)現(xiàn) Android 剛和我們度過第一個十年。十年前我們更多的討論桌面應(yīng)用與 Web,十年后我們專注在一個小屏幕,享受移動應(yīng)用給我們帶來的多彩世界。
移動應(yīng)用(即我們?nèi)粘Kf的「原生」應(yīng)用程序),通常是指某一移動平臺所特有的應(yīng)用程序。通過使用特定平臺所支持的開發(fā)工具和語言進行開發(fā),你可以直接調(diào)用系統(tǒng)提供的一些 SDK API。當(dāng)下流行的移動操作系統(tǒng)中,我們使用 Java 或 Kotlin 調(diào)用 Android SDK 開發(fā) Android 應(yīng)用,或通過 Objective-C 或 Swift 調(diào)用 iOS SDK 開發(fā)可以上架 App Store 的應(yīng)用。凡事沒有銀彈,移動開發(fā)也是如此。簡要來看,原生應(yīng)用開發(fā)具有以下優(yōu)勢:
1. 可獲取平臺全部開放功能,比如攝像頭,藍牙等;
2. 用戶訪問應(yīng)用的感受通常是速度快、性能高、體驗好的;
而其缺點也很明顯,主要有:
1. 為特定平臺開發(fā),綜合成本高,不同平臺維護需要人力成本;
2. 動態(tài)化能力弱,大多數(shù)情況下,新功能更新只能發(fā)版;
說到動態(tài)化,一次編碼便可運行在任何平臺的 Web 讓我們記憶深刻。而針對移動端存在的這些問題,為了在提高體驗的同時賦予應(yīng)用動態(tài)化能力,誕生了一批又一批的跨平臺移動開發(fā)解決方案。根據(jù)實現(xiàn)方式的不同,我將它劃分為三個時代:
1. 青銅時代。在該時代的框架主要采用 Webview 容器(廣義)進行內(nèi)容渲染,并借助原生代碼預(yù)置用以暴露給 JavaScript 調(diào)用的一部分系統(tǒng)能力,而這類協(xié)議則為我們通常說的 JavaScript Bridge;這個時代的框架在 Web 與 Native 間還有比較明顯的界限,大家各司其職(UI 渲染與系統(tǒng)功能調(diào)用);
2. 白銀時代。在這個階段我們?nèi)匀挥?JavaScript 開發(fā),但繪制已經(jīng)交由 Native 接管,展現(xiàn)在用戶面前的 UI 借助的是 JavaScript VM 的解析與 Native Widgets 的組合展示;
3. 黃金時代。不同于前一個時代,由于 Native Widgets 在 UI 上的「不盡如人意」,這個時代對方案起了一個新概念——自繪引擎,通過它在底層的繪制實現(xiàn)上來抹平不同平臺上界面開發(fā)的差異,UI 上真正做到了「每一個像素點可控」。雖然涉及到平臺層時還是需要原生開發(fā)介入實現(xiàn)相應(yīng)插件,但這已是三種跨平臺移動開發(fā)方案中最靈活的一種了。
二、問題
我們常說 Web 最終將一統(tǒng)天下,也常聽見 Web 在離我們遠去的聲音。但至今在終端 UI 上也沒有迎來一個完美的解決方案,這是因為在不同階段、不同實現(xiàn)上,都存在很多現(xiàn)實問題。讓我們再回顧一下這三個時代:
1. 青銅時代:采用 Webview 渲染的方案雖然成本低、部署迅速,但仍難以 cover 富交互的用戶界面與復(fù)雜手勢的快速響應(yīng);
2. 白銀時代:利用 JavaScript 調(diào)用 Native 代碼操作 UI 的方案雖然解決了不少渲染問題,但是跨平臺 Native Widgets 的差異仍然是個問題,這使得我們在 UI 上要做一些「妥協(xié)」,而存在于 JavaScript 與 Native 間的通信成本在一些場景下仍會使這種方案成為「累贅」;
3. 黃金時代:直接使用底層 API 進行繪制在執(zhí)行效率上大步邁進,看似已經(jīng)是終極解決方案,但大家是否想過,為什么被世人「不堪」的 Web 存在這么多年,不但沒有消亡反而愈發(fā)繁榮,以至于我們常說「任何能用 JavaScript 實現(xiàn)的應(yīng)用,最終都必將用 JavaScript 實現(xiàn)」;
注:「累贅」問題可詳見 Flutter 中文網(wǎng)關(guān)于移動開發(fā)技術(shù)一章的 介紹 。
其他還有一些問題值得思考,比如:
- 在今天,針對每個移動平臺單獨開發(fā)一套代碼,成本是否太高?
- 自繪引擎在操控 UI 上已經(jīng)足夠自由,但當(dāng)初這種解決方案為什么沒有火起來?
- 快速開發(fā)與部署、多端可訪問的 Web 開發(fā)模式,在當(dāng)下以及未來是否還會持續(xù)過去的增長勢頭?
三、What is Flutter
帶著這些疑問,我們走進全文的主角——Flutter。從2017年第一個 Alpha 版到上個月 Flutter Live 發(fā)布的 1.0 版本,F(xiàn)lutter 正獲得越來越多的關(guān)注目光。很多聽到這個詞的同學(xué)可能會感慨,似乎 UI 技術(shù)迎來了終極解決方案。我們先看看官方對它的定義:
Flutter 是 Google 用以幫助開發(fā)者在 iOS 和 Android 兩個平臺開發(fā)高質(zhì)量原生 UI 的移動 SDK。Flutter 兼容現(xiàn)有的代碼,免費并且開源,在全球開發(fā)者中廣泛被使用。
看看 Flutter GitHub Star 的變化趨勢,會發(fā)現(xiàn)每一個陡增都預(yù)示著 Flutter 的一次重要版本發(fā)布。在深入了解之前,我們來看幾個用 Flutter 做的 App,感受下官方所述的 Beautiful 到底是什么樣子的。
四、How is Flutter
看上去好像還不錯,但 Flutter 究竟有哪些與眾不同呢?我們按照官方描述的四個方面,分別來說說:
1. Beautiful - Flutter 允許你控制屏幕上的每一寸像素,這讓「設(shè)計」不用再對「實現(xiàn)」妥協(xié);
2. Fast - 一個應(yīng)用不卡頓的標(biāo)準(zhǔn)是什么,你可能會說 16ms 抑或是 60fps,這對桌面端應(yīng)用或者移動端應(yīng)用來說已足夠,但當(dāng)面對廣闊的 AR/VR 領(lǐng)域,60fps 仍然會成為使人腦產(chǎn)生眩暈的瓶頸,而 Flutter 的目標(biāo)遠不止 60fps;借助 Dart 支持的 AOT 編譯以及 Skia 的繪制,F(xiàn)lutter 可以運行的很快;
3. Productive - 前端開發(fā)可能已經(jīng)習(xí)慣的開發(fā)中 hot reload 模式,但這一特性在移動開發(fā)中還算是個新鮮事。Flutter 提供有狀態(tài)的 hot reload 開發(fā)模式,并允許一套 codebase 運行于多端;其他的,再比如開發(fā)采用 JIT 編譯與發(fā)布的 AOT 編譯,都使得開發(fā)者在開發(fā)應(yīng)用時可以更加高效;
4. Open - Dart / Skia / Flutter (Framework),這些都是開源的,F(xiàn)lutter 與 Dart 團隊也對包括 Web 在內(nèi)的多種技術(shù)持開放態(tài)度,只要是優(yōu)秀的他們都愿意借鑒吸收。而在生態(tài)建設(shè)上,F(xiàn)lutter 回應(yīng) GitHub Issue 的速度更是讓人驚嘆,因為是真的快(closed 狀態(tài)的 issue 平均解決時間為 0.29天);
注:數(shù)據(jù)源自五、Why use Flutter
為什么要使用 Flutter?僅僅因為他是「Google 下一代操作系統(tǒng)」Fuchsia OS 的內(nèi)置 UI SDK 么?
回答 ,我嘗試簡單解讀一下:
讓我們看的再詳細一些,上一張 Flutter 系統(tǒng)架構(gòu)圖,根據(jù)之前在問題「開發(fā)跨平臺app推薦React Native還是flutter?」下的從上至下分別為 Framework,Engine 和 EmEmbedder:
- Framework 層是框架使用者需要直接面對的,包含文本/圖片/按鈕等基礎(chǔ) Widgets、渲染、動畫、手勢等。如果你寫 Flutter 應(yīng)用,那么大致可以理解為調(diào)用這些 package 然后再用 Dart 「拼裝」些自己的代碼。
- Engine 層使用 C++ 實現(xiàn),這一層包含 Skia,Dart 和 Text。后兩個不太熟,說說 Skia。這是一個二維圖形庫,提供了適用于多種軟/硬件平臺的通用 API,既是 Chrome,Chrome OS,Android,F(xiàn)irefox,F(xiàn)irefox OS 等產(chǎn)品的圖形引擎,也支持 Windows 7+,macOS 10.10.5+,iOS8+,Android4.1+,Ubuntu14.04+ 等平臺;Dart 可能包含 Dart Runtime 等(JIT/AOT),Text 則負責(zé)文字渲染部分。
- Embedder 是一個嵌入層,做的事情是 Flutter to Platforms。比如渲染 Surface,線程設(shè)置,插件等。Flutter 的平臺層很低,比如 iOS 只是提供一個畫布,剩余的所有渲染相關(guān)的邏輯都在 Flutter 內(nèi)部,而這就是 Flutter 所宣傳的可以精準(zhǔn)控制每一個像素的原因;但不可否認,對于插件部分,還是需要特定操作系統(tǒng)底層的建設(shè)(比如支付、地圖等)。
有沒有對 Flutter 更清晰一些?
如果說再舉一點可以打動你使用 Flutter 的地方,那就是 animation 了。利用 Flare 你可以輕松構(gòu)建支持 Flutter 的動畫效果。這有點像十年前用 Flash 做關(guān)鍵幀動畫的感覺。
當(dāng)然,F(xiàn)lutter 和 Dart 團隊的不斷努力和優(yōu)化更是說服你選擇 Flutter 的理由之一。在剛不久前結(jié)束的 D2 上,Google 工程師介紹了為什么 Flutter 可以如此快,比如 Dart 在運行時更少的 malloc,F(xiàn)lutter 應(yīng)用運行時有更少的處理環(huán)節(jié)(跳過 Android/Chromium),F(xiàn)lutter 在渲染布局上更高效的遍歷過程等等。
面向未來,讓你在 Flutter 上下注的因素更少不了 HummingBird 和 Flutter for Desktop。STAY TUNED FOR GOOGLE I/O 2019!
六、Code with Dart
利用 Flutter 提供的腳手架,做一個簡單的 Demo 你甚至只需要寫更改兩個文件:main.dart 和 pubspec.yaml。作為前端,你可以將它們比做 index.js 與 package.json 吧。詳盡的代碼可見 https://gist.github.com/hijiangtao/2b58ab07d3d7ed96aa0f868140c906e5 .
七、Take away
人的記憶是短暫的,說了這么多,如果說本文想給大家?guī)バ┦裁此伎嫉脑?,我覺得可以總結(jié)成下面五句話:
1. RECAP / 在移動端跨平臺開發(fā)方案的歷史更迭中,我們從 Webview 加 Bridge 到 React Native 再到如今吸引大家目光的 Flutter,終端 UI 技術(shù)是否真的迎來了終極解決方案我們不得而知,但通過簡單回顧了這條歷史長河上出現(xiàn)過的幾場光輝,希望借他們的發(fā)展身影能給從事前端的大家?guī)ヒ恍┨鰳I(yè)務(wù)代碼的全局思考;
2. WHAT / Flutter 是什么:Google’s Portable UI Toolkit。它起源于移動端,但目光遠不止眼前的茍且。
3. HOW / Flutter 有四個特點,分別是 Fast, beautiful, productive 以及 open。這些能力源于其背后 Dart、skia 和更多技術(shù)的支持,了解這些有助于幫助我們更清楚一個完整的 UI 系統(tǒng)由哪幾個部分構(gòu)成,以使我們對上層建筑有更立體的感受。
4. WHY / 為什么選擇 Flutter,我在分享中介紹了不少原因,有系統(tǒng)設(shè)計的分析,有開放的學(xué)習(xí)態(tài)度,也有面向未來的 Mobile and beyond.
5. END / 如果你對 Flutter 感興趣請不要忘記對 Google I/O 保持關(guān)注。對身邊的新技術(shù)時刻保持好奇,做一個快樂的 Geek!
大浪淘沙,下一個十年我們又將身在何方?希望我的分享能讓你有所收獲。文中有誤的地方歡迎評論指出,關(guān)于 Flutter 的更多內(nèi)容歡迎一起討論。謝謝。
背后的故事1:很多前端工程師在最初聽到 Flutter 時都充滿疑惑,為什么 Flutter 選用了 Dart,而不是使用 Web 技術(shù)或者是 JavaScript 語言來實現(xiàn) Flutter 框架。其實 Flutter 中有不少內(nèi)容便是吸收自 Web 社區(qū),比如 tree shaking 和 hot reload。但 Flutter 另一個鮮為人知的故事是團隊中大部分成員都具有 Web (Chromium) 背景。如果你看過 Flutter Live,應(yīng)該知道 Flutter 與 Dart 團隊的人數(shù)并不多,大致就頭像墻中列出的那些,在最初設(shè)計上,他們也曾反復(fù)考慮 Web 技術(shù),而在語言選型上也考慮過 JavaScript。應(yīng)該不會有人比他們更了解 JavaScript 與 Web 了吧,但你看看這些開發(fā)過 Chromium 的人最后還是放棄了 JavaScript,我們有理由相信他們是經(jīng)過深思熟慮后做出的決定。按照 Google 工程師的話來說就是「我們關(guān)注包括 Web 技術(shù)在內(nèi)的很多技術(shù),我們?nèi)∑渚A并勇敢地扔掉歷史包袱?!?/p>
背后的故事2:在去年一年中,我們聽到的 Flutter 聲音更多是源自客戶端開發(fā)者,但自 1.0 發(fā)布后,吸引到了來自前端同學(xué)越來越多的關(guān)注。這一點和嚶嚶在「2019 前端技術(shù)規(guī)劃該包含什么?」中 回答 提到的現(xiàn)象類似。但前端同學(xué)有沒有想過,F(xiàn)lutter 起源于移動端,現(xiàn)有 Flutter 雖然來自曾經(jīng) Chromium 團隊,但整體對客戶端開發(fā)的友好度是要高于前端開發(fā)的,畢竟有一個平臺層插件擺在那里,再看看 Flutter 即將推出的 HummingBird,乍一看是 Web 的福音,但這也只是為 Flutter to Web 提供了途徑,而非為前端提供了增強 Web 的可能。從某種意義上說,Web 的疆土正在逐漸縮小。這一次,我們是否真的要失業(yè)了呢?
注:關(guān)于 Google 工程師的一段話描述意譯自 Google 工程師在 Flutter 圓桌會上的相關(guān)言論,有出入。