閒魚 Flutter 實踐與思考

Flutter 作為革命性的跨終端解決方案,於 2018 年 12 月正式發佈,僅用了不到一年的時間就在 GitHub 和 StackOverflow 上獲得了比 React Native 更高的知名度。那麼所有項目都應該使用 Flutter 嗎?並非如此。沒有最好的框架,只有最適合的框架。是什麼原因讓閒魚選擇了 Flutter?閒魚在架構 Flutter 化這方面有著怎樣的經驗與挑戰呢?帶著這些問題,InfoQ 記者採訪了 GMTC 專題出品人於佳(宗心),以下為採訪實錄。

迎接大前端時代

手淘客戶端架構升級

我從 14 年開始參與手機淘寶的研發體系的升級,彼時正值淘寶 all in 無線的時期,大量研發人員湧入客戶端進行開發工作。開發人員變多了,也帶來了一個問題:當一百名以上的同學開出對應數量的分支進行研發時,在協同效率上出現了巨大的瓶頸,代碼衝突十分嚴重,解決衝突的成本也著實難以承擔。

手淘架構組臨危受命,在沒有任何業界先例的情況下,通過對比服務端的解決方案找到了工程拆分的解決方法——模塊化。具體的方案是設計一個類似 Spring IoC 能力的輕量級容器,以保證各模塊間的通信機制及接口調用標準。這樣做的好處是:

各個模塊通過接口的形式進行能力的對外暴露;

在集成階段通過二進制包的方式保證了 App 整包的編譯效率和各業務線的代碼隔離。

這個方案極大的減少了集成的成本,也為後續手淘的快速迭代提供了保障,正因如此,這套基礎架構的方案一直沿用至今。在前端急速發展的今天,端側工程拆分也仍是大型客戶端上常見的方法,同時對行業也有明顯的借鑑意義。

天貓移動端架構合併

而淘寶和天貓的移動端架構合併則是手淘架構升級之後的事情了。有一天主管找到我並提出要基於手淘的新架構幫助手機天貓進行研發體系升級,進行一些底層能力的整合,諸如網關、H5 容器等一系列端側中間件標準。

如果說之前在手淘架構升級的過程中我的角色是執行者,那麼這次的角色就有了很大的變化。一方面要修改代碼,另一方面還要進行技術佈道,同時還要說服一線開發和對方的主管,不單單是對技術與代碼的執行者。外派的近一年時間中,我作為橫向推動兩個大的 BU 做架構整合的人,為了手機天貓的研發體系可以順利升級,經歷了很多不為人知的艱辛。雖然過程十分曲折,但結果是好的,最後我和同事一起完成了架構的合併。自此,手淘正式成為移動中臺開始對集團輸出能力。

閒魚是在什麼時候決定採用 Flutter 的?在此之前閒魚 App 的客戶端技術選型是怎樣的?

2014 年,集團內部孵化了閒魚這個創業項目,次年我加入了閒魚團隊。當時的閒魚人力非常有限,很多基本的用戶體驗問題都沒有解決,因此閒魚先推進了客戶端基礎設施全面擁抱淘寶的步伐,完成了移動中臺底層中間件的對接以及配套基礎設施的遷移。這樣在極大降低了成本的同時也使閒魚大幅度提升了性能和穩定性。此後的兩年中,閒魚團隊的規模一直比較小,正因如此,我們一直在尋找提升研發效率的方案,並進行很多不同的嘗試,後面會詳細說明。

再經歷了不同的嘗試後,閒魚選擇了 Flutter。而從“瞄”到 Flutter 到確定採用的這一過程,大概可以歸為三個階段:

1、2017 年,閒魚開始進行對 Flutter 的技術調研,思路是如何令小團隊的研發效能大幅度提升。之後閒魚又進行了前期的驗證及與 Google 的合作;

2、2018 年,開始進行實際的業務驗證;

3、2019 年,我們確認團隊可以駕馭這項技術後,開始大規模落地與推進 Flutter 在閒魚的應用。

目前閒魚線上的主鏈路幾乎已經完全擁抱 Flutter,僅剩的一些業務也會在後續逐步進行遷移。

閒魚的 Flutter 化架構演進之路

閒魚在確定 Flutter 之前做過哪些嘗試呢?首先來看當時的背景。

眾所周知,在阿里的前端搭建體系裡,Weex 是主流方案,但當時閒魚的產品主鏈路需要一個高性能、不降級的方案,該場景下這一類技術無法滿足閒魚客戶端的需求。因此是否適合閒魚客戶端主鏈路使用成為了我們對技術方案的選擇的主要考慮方向。

Native & Weex

首先我們想到了 Native。起初我們嘗試在 Native 雙端都設計有同樣概念的編程框架(OC/Java),統一端側的代碼標準,但落地的過程中發現兩套代碼及兩個平臺的差異很難避免。

然後閒魚又嘗試了集團的 Weex 作為主鏈路的方案。首先,閒魚對主鏈路的穩定性要求較高,由於 Weex 的動態特性,線上只有一套代碼,就有可能造成老版本的兼容性問題。在產品主鏈路,即使有千分之一的頁面由於兼容性問題也會引起輿情問題,這是業務方無法接受的。其次,Weex 的配套設施對客戶端開發來講存在一定成本。最後我們得出結論,Weex 在導購體系和活動等場景下有比較好的性能提升且集團的配套設施比較完善,但可能不太適用於主鏈路的業務。

Flutter

在 Native 和 Weex 都不適用的情況下,閒魚繼續著探索之路,在持續探索的過程中,偶然間發現了 Flutter 這個方案。首先,從其設計理念來看,Flutter 具有更好的多端一致性,優秀的性能,高效的研發配套工具,更貼近客戶端的研發體系等等。從客戶端的角度出發,我們覺得這就是主鏈路苦尋的方案。其次,Flutter 背靠 Google 的同時又是開源產品,這點也給了我們信心。所以,閒魚團隊決定嘗試 Flutter。

RN

提到 Flutter 就自然會想到 RN,對於 RN 來說,閒魚團隊在落地過程中並沒有直接使用過。我認為 RN 和 Weex 比較像,整個研發體系包括工具鏈上面還是更偏向前端,Weex 的主要優勢是研發效率和動態性,在性能側相比 H5 會有一些優勢,因此比較適合代替現有的 H5 方案。而 Flutter 更偏向客戶端的研發體系,研發效率和性能以及多端的強一致性是它的優勢,基於這些優勢,特別適合代替現有主鏈路的 Native 方案。

閒魚 App 引入 Flutter 後,在效率、性能 / 體驗和質量三個關鍵點上的表現如何?

效率

在引入 Flutter 前,開發間協同成本很高,導致協同效率低,例如雙端開發分別需要與測試協同,雙端開發之間需要協同等等,這樣就導致協同成本過高。通過 Flutter 的落地,協同效率至少提升一倍。在目前的閒魚大部分需求都是一個客戶端同學獨立完成的,研發側在效率部分目前有將近 80% 左右的客戶端代碼是雙端共享的,而且比例還在提升。

性能 & 體驗

在早期我們做過一個實驗,在低端機上,Flutter 開發的新詳情的性能是優於老詳情的性能的。由於對繪製側的統一優化以及對 GPU 的使用,讓很多開發同學可以在複雜場景寫出性能不錯的代碼。性能側目前還有很多工作要做,由於 Flutter 的性能基線跟 Native 不太一樣,在業內嚴謹的性能標準還沒有出現。閒魚團隊最近還在與 Google 的同學溝通,看後續是否能一起定義 Flutter 側性能的行業標準,並幫助完善部分 Flutter 社區的性能優化工具。

質量

質量側 iOS 在內存消耗以及 crash 率上略高於 Android,因此閒魚在 Engine 側做了一些優化和定製,阿里內部有比較嚴格的對 crash 率的標準,可以說目前看下來質量滿足上線要求。

落地過程中有沒有遇到一些挑戰呢?閒魚是如何解決這些挑戰的呢?

閒魚 App 引入 Flutter 後,在多方面都有了顯著的提升,但落地過程並非一帆風順,挑戰一直伴隨著整個落地過程。大致分為三個階段:

第一個階段主要的問題是行業內沒有把 Flutter 放入已有工程體系進行開發的先例。

我們在這個過程中從工程架構、混合棧調用、打包構建、協同模式上都做了一些創新,保證了 Flutter 能融入已有閒魚的客戶端工程體系之內。後續我們推動了 Google 在 milestone 的變更,重點開始關注混合架構下的研發體驗和配套設施,就是今天大家看到的閒魚了。同時這個過程中我們沉澱出了現在團隊在開源社區推出的混合棧框架 Flutter_Boost。

第二個階段主要的問題是性能和穩定性。

在初期幾版灰度上線過程中,我們使用的是 v0.5.6 版本,當時還不是特別穩定,我們經常會因為 crash 以及一些諸如手勢衝突相關的 bug 修改引擎並同步給 Google 的同學。另外,在中國特有環境下的適配問題,也需要我們對引擎依賴的一些三方庫進行修改以適配各個廠商特有的 ROM 帶來的 bug。我們還發現音視頻和圖片的內存佔用和 CPU 消耗上有不少問題,這個過程中我們也做了針對性的改進。

第三個階段是 Flutter 大規模的推廣的問題,真正意義上讓團隊每個同學都可以開發 Flutter 的代碼。

而這一過程中,主要的挑戰在於如何讓沒有經驗的同學在短時間內可以寫出高水平的 Flutter 代碼並解決代碼隔離問題。這部分我們通過對 Redux 的標準進行擴展,前後經歷了三個版本的迭代討論,最終在保持 Redux 核心三原則的基礎上,擴展出了 Component 機制來解決組件複用以及代碼隔離的問題,這個在多人協同的複雜業務上是非常重要的。我們也將其開源並命名為 Fish-Redux,歡迎大家使用。

Flutter 的變化與展望

改進與優化

閒魚在混合架構的演進的過程中,與 Flutter 相關的改動主要有兩部分,第一部分是針對於引擎本身的 Bug 進行的修復工作,隨著 Flutter 的日益完善,這部分目前對大家的參考意義不太大。

而另一部分則是關於性能的優化與改進。有兩個比較典型的例子:

1、第一個是混合開發的開始階段,如果每次都創建新的 FlutterView 進行渲染,會造成內存的嚴重消耗,但如果全局只使用一個 FlutterView 又會造成 Native 和 Flutter 頁面棧管理複雜。基於這個問題我們研發出 Flutter_Boost 的方案,既保證了全局只有一個 Engine 實例共享,又通過該框架屏蔽了 Native 和 Flutter 頁面棧管理複雜的問題。

2、另一個是針對圖片和視頻在 Flutter 頁面上渲染的優化。主要的策略是通過改造 Flutter Engine 將繪製部分的 API 做擴展,允許 Flutter Engine 接受 TextureID 的直接傳遞,保證 Flutter 頁面在使用外接紋理繪製的過程中整個調用鏈路足夠短,使用的內存足夠少。這個方案當然也有缺陷,就是需要改 Engine,通過去年的優化,我們已經找到了類似縮短鏈路又不改引擎的方案,後續也會分享給大家。

後續規劃

後續團隊的 Flutter 發展規劃大體有幾個方面:

  • 目前需要基於閒魚現有的技術體系,為集團賦能。我們正在跟淘寶架構團隊進行橫向的聯通,通過貢獻我們現有能力的方式,推進 AliFlutter 的落地,以幫助集團更多的團隊。當然閒魚主要是輸出技術方案,中臺本身還是由其他團隊來支持和負責。
  • 閒魚也有自己的主線,我們希望推進技術棧的歸一,保證端和雲的編程模型可以進行歸一。舉個例子,未來的業務團隊一個人就可以從端到雲進行開發,這對於構建柔性的技術組織有巨大好處,這種類型的組織極大的減少了技術棧之間的協同,對企業成本和效率有明顯提升。
  • 我們也有非常多貼近業務的技術方案在進行嘗試中。比如動態模版框架和輕量級遊戲引擎,未來可能會產生一些機會和變化。

我們目前團隊的架構師,Fish-Redux 的作者吉豐將於今年的 GMTC 上給大家分享詳細的架構設計和應用場景,歡迎大家參加。

您覺得 Flutter 在未來的發展趨勢如何?跨平臺開發會出現大一統的局面嗎?

從目前的方案上來看,Flutter 是行業內跨平臺方案解決的較為徹底的一個,且背後有 Google 支持。大量的頭部公司都有團隊在持續投入和研究,因此我認為作為一種跨平臺的解決方案,未來 Flutter 有機會成為主流的開發方式之一,另外由於它是跨終端的解決方案,未來在 PC 端和 IoT 設備端也會有一定的機會。

但 Flutter 一定不是唯一的方案,而且不可能完全代替 Native 開發。從成本和效率來說,若 Flutter 後續將生態完善起來,對於絕大部分小前臺的 App 或需要多個終端進行投放的 App 來說將會是一個不錯的選擇,這也是大廠在推進 Flutter 上都比較積極的原因。對於大廠來講,百花齊放是非常有必要的,大廠 all in 某一種技術是非常危險的選擇。

而對於跨平臺開發來說,行業內一直都在不斷推陳出新,所以我覺得不太可能出現大一統局面。另外,跨平臺開發框架其實是非常多的,除了 Flutter,Weex 和 ReactNative,我們去看 Qt,去看 Cocos2d-x 包括瀏覽器技術都是跨平臺技術。技術選型跟團隊架構師定義的當前問題、團隊同學的知識結構、上下游的技術架構都有一定的關係,沒有最好的技術,只有相應場景下具有優勢的技術。

您觀察到的大前端發展趨勢是怎樣的,對年輕化的前端、客戶端開發人員來說應該怎樣持續地學習成長?

除了傳統的跨平臺方案以外,端計算,AR/VR,5G 下的音視頻技術等等都是大家經常會提到的熱點,這些講起來有點虛了,我還是更多從一線的客戶端開發人員的角度去看這個事情吧。

找到核心不變的部分

首先,端側開發者永遠都是最直接面向用戶的,關注的重點主要集中在交互體驗,渲染效果,端側的性能等。但隨著技術革新,新的設備與操作系統的出現,這幾點可能會略有差異,但很多原理都是相通的。隨著大前端入門門檻的降低,開發者若要保持競爭力,就需要在相應的領域裡深耕,比如成為性能優化領域的專家,做一些別人無法做到的事情。

將已有技術改良優化

跨其他技術體系借鑑衍生了很多新的機會。比如端計算,除了現在大熱的推理引擎以外,還有很多原來在服務端的技術方案可以轉移到客戶端。閒魚團隊目前在端側就有實現輕量級的 CEP 引擎,或許不能像服務端 CEP 那麼複雜,但是對於支撐實際的用戶增長業務,完成實時的用戶觸達有比較好的效果。傳統的 App 開發跟遊戲技術的融合,也會產生一些新的想象力。

產生創新

拿 Flutter 來說,今天的混合開發上面遇到的問題,在 Native 和遊戲框架融合的場景下也會出現,Flutter 側我們使用的外接紋理的方案,也是常見的混合渲染會使用的方案,所以是有很多共通之處的。因此當我們接觸一個新的技術時,搞清楚底層原理,舉一反三,定義出它的優勢場景和問題並嘗試通過其他類似領域遇到過的經驗做優化,這種做法遠好於學了一門新技術只做上層的開發,最後變為專業的 UI 還原工程師,要好的多。

保持好奇心,對技術追根問底的精神,日常多做總結養成好習慣,同時拓寬自己的技術視野,比如經常看看 InfoQ 的技術內容,看看別人是怎麼做的,很重要。

嘉賓介紹

於佳,花名宗心,閒魚技術團隊客戶端負責人。2012 年應屆畢業加入阿里巴巴,經歷集團無線化轉型的重要時期,參與過集團多款重量級 App 以及移動中間件的設計與開發,多年客戶端老兵。2015 年加入閒魚客戶端團隊負責端架構和團隊建設,工作期間完成了基於 Flutter 混合架構的閒魚客戶端的整體架構設計,在工程體系上完善了針對 Flutter 的持續集成以及高可用體系的支撐,同時推進了閒魚主鏈路業務的 Flutter 化。


分享到:


相關文章: