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