1. 程式人生 > >【開發經驗】淺談flutter的優點與缺點

【開發經驗】淺談flutter的優點與缺點

本文預設你已經是開發者,並對Flutter有基本的瞭解,但是還未深入使用,希望瞭解Flutter在商業級(而非demo)的專案中的優勢與劣勢。

很多前端開發者應該都尋找過跨平臺的App解決方案,包括沒有同時獨立開發iOSAndroid雙端原生app的開發者,應該都接觸過或者看到過Google的Flutter框架。我對於iOS原生開發與基於Vue.js的web開發比較熟悉,並在一個正在進行的藍芽硬體專案中應用了Flutter框架,經歷的漫長的適應,在本文中我將以iOS原生開發者與web開發者的視角看待Flutter框架,簡單羅列Flutter的優勢與缺點。

Flutter優點

Flutter的優點非常明顯,如果你選擇一個跨平臺框架,與眾多基於html

的跨平臺框架相比,Flutter絕對是體驗最好,效能與構建思路幾乎最接近原生開發的框架。

  • 效能強大,流暢

Flutter對比weexreact native相比,效能的強大是有目共睹的。基於dom樹渲染原生元件,很難與直接在原生檢視上繪圖比肩效能,Google作為一個輪子大廠,直接在兩個平臺上重寫了各自的UIKit,對接到平臺底層,減少UI層的多層轉換,UI效能可以比肩原生,這個優勢在滑動播放動畫時尤為明顯。

  • 路由設計優秀

Flutter的路由傳值非常方便,push一個路由,會返回一個Future物件(也就是Promise物件),使用await或者.then就可以在目標路由pop,回到當前頁面時收到返回值。這個反向傳值的設計基本是甩了微信小程式一條街了。彈出dialog

等一些操作也是使用的路由方法,幾乎不用擔心出現傳值困難

  • 單例模式

Flutter支援單例模式,單例模式的實現也非常簡單。單例模式很好的解決了一些問題。相比之下,js的單例則並不是一個真正的單例,或者說不是一個簡單的單例,這也是受限於js所執行的環境。單例模式並不總是合理的,容易被濫用。但是在App的初期開發中,往往一個容易實現的單例可以幫助我們快速完成一些邏輯的搭建。

  • 優秀的動畫設計

Flutter的動畫簡單到不可思議,動畫物件會根據螢幕重新整理率每秒產生很多個(一般是60個)浮點數,只需要將一個元件屬性通過補間(Tween)關聯到動畫物件上,Flutter會確保在每一幀渲染正確的元件,從而形成連貫的動畫。這種十分暴力的操作在Flutter

上卻看不到明顯的卡頓,這也是Flutter的一個魔力所在。相比之下其他跨平臺框架幾乎不能設計動畫……往往會遭遇非常嚴重的效能問題。

  • UI跨平臺穩定

Google直接在兩個平臺上在底層重寫了UIKit,不依賴於Css等外部直譯器,幾乎不存在UI表達不理想,渲染不正常的情況,可以獲得非常穩定的UI表達效果。Css換個瀏覽器就有不同的表現,基於Css的跨平臺框架很難獲得穩定的UI表現。

  • 可選靜態的語言,語言特性優秀

Dart是一個靜態語言,這也是相對於js的一個優勢。Dart可以被編譯成js,但是看起來更像java。靜態語言可以避免錯誤,獲得更多的編輯器提示詞,極大的增加可維護性。很多js庫也已經用ts重寫了,Vue3.0的底層也將全部使用ts編寫,靜態語言的優勢不言而喻。

Flutter缺點

  • 假裝是跨平臺,躲不開的原生平臺與原生程式碼

這是最大的問題,跨平臺框架說白了就是UI跨平臺,最後還是在原生平臺執行,本來兩個平臺就有天壤之別,一套程式碼就想吃掉iOS和Android在實際應用之中其實根本就不現實。Flutter具有與原生程式碼互相呼叫的能力固然非常科學,但是問題反而顯得更加明顯——我一個前端工程師上哪裡去知道什麼是UIViewController,什麼是Activity呢?我要是雙端都熟悉,學習Flutter就顯得很沒有必要。這是一個很矛盾的點,特別是在團隊裡,只有幾個前端突然想學Flutter,是絕對做不來大專案的,如果有原生開發者,那就沒必要搞Flutter了。

  • 組合而不是繼承的思路

Flutter提倡“組合”,而不是“繼承”。在iOS開發中,我們經常會繼承UIView,重寫UIView的某個生命週期函式,再新增一些方法和屬性,來完成一個自定義的View。但是在Flutter中這些都是不可能的——屬性都是final的,例如你繼承了了一個Container,你是不能在它的生命週期中修改他的屬性的。你始終需要巢狀組合幾種Widget,例如RowContainerListViewWidget。這種方法非常不符合直覺,初學時很難想明白如何構建一個完整的元件。

  • Widget的型別難以選擇

FlutterWidget分為StatefulWidgetStatelessWidget兩種,一種是帶狀態的一種是不帶狀態的,剛開發的時候很難想明白用哪個,因為StatelessWidget也能存值,其實區別就在於框架重構UI的時候會使用State來重構,如果是StatelessWidget,暫時存進去的值就沒了。但是問題遠不止這麼簡單,好在只是有點麻煩,並不影響產品效能。

  • 糟糕的UI控制元件API

雖然google儘可能的讓我們通過建構函式定製化Widget,但是也難免有遺漏的。例如,又一次我想修改一個Appbar的高度,居然沒有找到關於高度的屬性,通過閱讀原始碼發現,高度是寫死(const)的。上文已經說過,無法通過生命週期來改變元件屬性,自己寫Appbar顯得非常沒必要,畢竟我還是想使用Appbar的各種方便的功能。最後我只能把他的原始碼全部複製出來,直接修改高度來使用。初學框架,和一些初級開發者是不可能有迅速閱讀原始碼的能力的(作為框架也不應該產生如此問題)。一些定製化的UI的Api設計經常有缺失,好在我已經基本習慣了。除了Appbar這種複雜的元件,自己寫一個小元件也並不費事。

  • 糟糕的資源管理設計

這裡是最蠢的,Flutter支援動態載入不同解析度的圖片,但是目錄設計太鬼畜了。簡單的說,Sketch匯出的多解析度資源,幾乎不可能直接拖到Flutter裡用,極其,極其,麻煩。

畢竟國情在此,要用Flutter,先買梯子。雖然有“在中國使用Flutter”指南,但是太麻煩,沒梯子開發Flutter,難度係數太高了,總不能碰到每個問題都花一整天尋找替代方案吧,先買好梯子圖個安心……

總結

Flutter主要的坑就在於需要非常瞭解原生的環境,其實跨平臺的框架都是如此,想要通過跨平臺的API就拿下雙端的開發任務,對認真學習的原生開發者來說也是不公平的。
主要的優勢則在於動畫流暢,很多開發者反應比原生安卓還流暢(存疑),至少在iOS上是看不到卡頓的,安卓上動畫也很穩定,效能上展示了Google的硬實力

本人是iOS原生開發者,亦熟悉Vue.js,小程式等前端開發,對Android開發與Reactive Naive不甚瞭解,本文乃是一些初級經驗與感悟,若有不當還請評論指正。