閒魚研發框架應用和探索

簡介:Flutter是開源的UI工具包,其能夠幫助開發者通過一套代碼庫高效構建多平臺精美應用,支持移動、Web、桌面和嵌入式平臺。在AliFlutter 系列第二場直播中,阿里巴巴閒魚無線技術專家梁治峯爲大家分享了閒魚在Flutter中研發框架應用和探索,從分別從三個方向介紹Flutter一體化研發模式、Flutter動態化能力、Flutter互動能力。

Flutter是開源的UI工具包,其能夠幫助開發者通過一套代碼庫高效構建多平臺精美應用,支持移動、Web、桌面和嵌入式平臺。在AliFlutter 系列第二場直播中,阿里巴巴閒魚無線技術專家梁治峯爲大家分享了閒魚在Flutter中研發框架應用和探索,從分別從三個方向介紹Flutter一體化研發模式、Flutter動態化能力、Flutter互動能力。

演講嘉賓簡介:梁治峯(花名:玄川),阿里巴巴無線技術專家,閒魚買家鏈路客戶端負責人,主導閒魚Flutter化的落地和研發框架演進。

本文內容根據演講視頻以及PPT整理而成。
觀看回放http://mudu.tv/watch/5466337

本次分享的主題主要包括以下五個方面:
一、閒魚Flutter研發框架使用現狀
二、Flutter研發框架下一代模式
三、Flutter研發框架下動態能力
四、Flutter研發框架下互動能力
五、後續規劃和展望

一、閒魚Flutter研發框架使用現狀

閒魚是一個側重於電商業務的平臺,因此隨着業務的不斷增長,系統的邏輯複雜度也在不斷提升。因爲屬於電商業務,所以對於流量和運營的數據具有較高的需要,因此在閒魚的體系中也需要具備動態性的能力,並且還需要通過增加特效的能力來增加用戶的感知,豐富用戶的體驗。

屏幕快照 2020-06-22 下午2.06.02.png

二、Flutter研發框架下一代模式

一體化模式

下圖中左側是傳統的客戶端-服務器架構。在這樣的CS架構下,對於客戶端開發者而言,往往都會經歷相似的痛點。當產品的需求過來,可能客戶端的開發同學並不能自己完成,而需要牽扯到服務端的開發,可能需要對於協議進行補充或者添加更多的接口能力。而對於後端開發同學而言,面對一個需求也可能需要領域服務的支持。這樣一來,一個貌似很簡單的需求,卻需要從客戶端到後端再到領域服務的相互協調,進而會影響需求的排期問題。而如果客戶端也可以寫服務端的代碼,這樣的問題是否就能夠被解決掉呢?

屏幕快照 2020-06-22 下午2.06.50.png

在目前閒魚所給予的FaaS框架下的一些場景中也存在上述痛點。如下圖所示的是傳統基於FaaS的模式,可以看出使用FaaS能夠將邏輯和UI徹底進行分離,但是在端上的邏輯部分,無外乎兩種,一種是數據的拉去和推送,另外一種是數據的主賬號。在後端也會有類似的邏輯,只不過此時不是客戶端找服務端要數據,而是服務端找各個領域層要所需要的數據,然後進行數據的加工,再將數據以面向客戶端協議的部分進行主賬號推送。而上述兩個部分存在着一定的邏輯割裂,並且也存在一定的重複工作,因爲數據轉化被執行了兩次。那麼,是否能夠將上述兩種邏輯合二爲一,並且讓端上的同學進行開發,同時將邏輯後端化呢?結合如今Serverless的能力,可以做到在輕量級能力下支持多語言的開發。

屏幕快照 2020-06-22 下午2.07.21.png

基於上述的背景,閒魚在今年實現了一體化的研發解決方案。在雲側兼容了集團通用的Gaia容器化能力,用Dart語言實現了容器化的部分。之所以使用Dart是因爲這部分與Flutter對應。阿里巴巴希望客戶端寫後端的情況與Flutter使用一體化的語言來完成,屏蔽兩者之間的差異。在端側研發了Nexus一體化插件,將現在面向Action的部分可以實現端側與雲側的一體化。這樣的好處在於在端側叫Action,在雲側也叫Action,而在端上進行開發的時候並沒有感知雲側Action的存在,這就是Nexus的核心作用。此外,現在面向於通信協議其實就是面向於API接口的一部分,這樣能夠實現端上的高性能和邏輯內聚。

屏幕快照 2020-06-22 下午2.07.40.png

這裏簡單介紹一下一體化框架的具體落地場景。對於下圖所示的閒魚下單的頁面而言,在原有模式下可能需要5個請求接口,這部分請求接口可能部分在端上,部分在雲上,並且通過一條信息流進行合併。這種情況下如果需要修改某種狀態就會非常複雜。在改造完成之後就將原來的5個請求接口全部實現Action協議化,這樣的好處在於雲端的模型統一了,無論是對於雲還是客戶端都在寫同樣的邏輯,只不過這樣的邏輯部署到了雲上。其次,還屏蔽掉了協議的具體部分,只留下了協議名稱。第三點好處在於實現了邏輯的歸一,所有的邏輯都實現了雲端化,大家在書寫這樣的邏輯時不會存在割裂,最終書寫的邏輯都是面向雲模型的狀態。第四個優點是冗餘代碼將會大大減少。而最大的好處在於形成了很好的業務的閉環,讓客戶端開發也可以應用開發的部分工作。

屏幕快照 2020-06-22 下午2.08.13.png

三、Flutter研發框架下動態能力

閒魚本質上主要是一個電商業務平臺,其在於流量側具有強運營時效的特性,很多的運營活動或者決策需要得到及時的響應,如果在這種情況下不具有動態性就會陷入被動。完整的動態性包括了邏輯動態性和UI動態性,但是在流量側部分更加註重UI動態性,輕邏輯重UI。接下來將與大家分享在Flutter側如何使用這樣一個微能力的解決方案。
屏幕快照 2020-06-22 下午2.08.41.png

動態模板

動態模板在阿里巴巴整個集團內部都是一套比較成熟的解決方案。首先,通過DX平臺編輯模板,編輯成二進制文件並生成模板下載鏈接,之後模板下載解壓,進行表達式或者事件的註冊,並對於數據進行綁定解析,使得組件得到渲染。藉助於集團動態模板的成熟方案,所需要解決的就是在Flutter側如何滿足DSL的UI表達,來實現UI佈局。

屏幕快照 2020-06-22 下午2.09.12.png

核心問題-Layout

熟悉安卓或者Flutter的人會發現這兩部分的UI表達其實是格格不入的,那麼如何在Flutter側實現一套安卓UI佈局呢?其實完整的UI表達是樣式+佈局+內容組合實現的。根據Flutter的源碼可以看出,在其佈局表達裏面,樣式、佈局、內容三個要素表達是徹底分離的。相反而言,在安卓的DSL的架構裏面,樣式和佈局是結合的,內容部分是分離的。如果將安卓的部分也進行拆分可以一一映射到Flutter中,雖然描述部分可以很容易地做映射,但是核心困難在於佈局部分,主要是關於大小的抽象性描述,因此需要了解在Flutter側是如何表達佈局的約束的。

屏幕快照 2020-06-22 下午2.09.34.png

其實在Flutter側主要有兩種對於佈局的約束設計,分別是盒子模型和條子模型,而以上兩種都是感性描述的約束性佈局。除此之外,還提供了30多個佈局的容器部分。這是因爲基於上面的感性描述的約束佈局情況下,Flutter可能會存在大量的冗餘代碼,在約束佈局情況下就會顯得特別複雜。另外一部分在於性能部分,感性描述遠遠沒有大於量行描述,因此Flutter提供的30多個量行約束是對於性能的考究。反觀安卓的佈局部分,相對比較少,大約爲4、5個,所以這裏的問題就是如何將安卓的佈局部分使用Flutter的佈局來表達或者描述。如果想要使用特性來做映射是很困難的,如果退而求其次,使用共性部分的盒子模型和條子模型似乎可以表達。

佈局表達

如果在端側已經完成對於動態模板樹形結構的解析之後,就能夠很容易地將樹形結構的節點實現如下圖所示的一拆三結構。第一層是裝飾層結構,中間層可以基於自低向上和自頂向下的計算規則重新計算出大小,最後一部分則是將內容想要表達的葉子界面進行Backup。爲了實現安卓這樣的佈局結構阿里巴巴引入了安卓的Spec Model模型,其很主要的作用就是表達當需要做依賴於內容適配等情況下,可以使用Min_width的最大估算來預估大小部分,再從自底向上來計算出實際的Size。動態模板在Flutter側的實現主要解決的就是這樣的側重點部分。
屏幕快照 2020-06-22 下午2.09.55.png

業務效果

整套方案經過閒魚一整年的打磨之後,已經有大量的業務上線和應用了。無論是卡片還是其他佈局部分,都能夠使用Flutter UI實現。
屏幕快照 2020-06-22 下午2.10.28.png

性能參考

動態性部分往往會和性能存在一定的博弈。在閒魚的實踐中得到的實際結果表明,使用動態模板的DSL來表達的性能還可以接受,線上的實際效果大約在55幀左右,相比於正常使用Flutter原生的60幀僅僅存在可被接受的一點差距。

屏幕快照 2020-06-22 下午2.10.49.png

性能的下一步探索

雖然目前的方案和Flutter原生僅存在5幀的差距,但是如果能夠進一步優化,還是有可能達到原生的性能要求的。下圖中分別展現了使用Flutter原生和DX寫的卡片佈局,可以直觀地發現在Flutter原生使用了大量的高階型特性表達,在DX中則基本都是常見的容器佈局,並且樹形結構的深度層次遠遠大於Flutter原生。DX中使得長度變大的部分在於裝飾性的佈局部分,因此可以嘗試地探索在DSL的表達部分將Padding在容器層進一步縮短結構,可能會提高FPS,也就是將現在的簡單容器佈局進行特性升級。

屏幕快照 2020-06-22 下午2.11.15.png

四、Flutter研發框架下互動能力

背景與現狀

在電商領域的業務裏面,很多業務想要通過遊戲化的方式創造更有表現力的交互體驗,創造新的業務玩法和價值。傳統的UI表達方式,越往後就會越受限,因此需要將UI和遊戲引擎的邊界打破,讓UI具有遊戲的豐富動效能力,也讓遊戲引擎具有UI的豐富控件能力。在傳統APP的框架下,所能夠做的無外乎嫁接遊戲引擎,而這樣的遊戲引擎和原來的APP是格格不入,也是不相通的,其能夠帶來的最大效果就是開闢一個獨立的頁面來承載遊戲,但這樣的方式似乎不是所想要達到的設計理念。在Flutter側,今年推出了Flame這個遊戲框架,其解決了單邊引用的過程。Flame使得在Flutter框架裏面可以將遊戲的控件進行合攏,但是無法實現在遊戲裏面合攏UI界面,因此提供了單邊能力。Flame雖然沒有完全解決雙邊打通的訴求,但是還是提供了很好的思路。
屏幕快照 2020-06-22 下午2.11.38.png

核心問題-融合

目前而言,所需要解決的核心問題就是將UI和遊戲引擎融合。Flame的表現形式其實就是將完整的遊戲封裝在起來,能夠很好地將遊戲插入到UI中。假如將Flame遊戲引擎的表達也用類似於RenderObject樹形結構的表達,就會形成兩棵Flutter體系下的樹結構,能夠很好地進行融合比對。閒魚在這樣的思路下進行了新的探索和嘗試,重新設計了一套互動遊戲引擎,彌補了Flame不能滿足的需求問題。

屏幕快照 2020-06-22 下午2.12.04.png

Candy整體設計

Candy是符合ECS標準的,與Flutter高度融合的原生開發高性能互動開發框架。Candy在架構設計上完全按照ECS的標準;在接口設計上對齊了阿里巴巴集團的互動EVA,使得集團內部在使用時不會對於接口感到陌生;在應用能力上,Candy完全融入了Flutter的繪製體系;在擴展能力上,Candy保留了遊戲子系統化能力的補充,能夠滿足UED主流能力,使得不同公司或者行業開發者能夠更好地使用自己所熟悉的工具體系。
屏幕快照 2020-06-22 下午2.12.25.png

效果

在閒魚中,簽到、換取閒魚幣等常用的按鈕在遊戲中使用了Flutter的遊戲控件,能夠非常簡單地將遊戲以Widget形式插入到Flutter頁面中,而這對於使用者而言不會產生任何感知。此外,對於傳統應用的開發者,也能夠很輕鬆地將具有動畫能力、遊戲能力的控件外透,並且與UI進行融合。
屏幕快照 2020-06-22 下午2.12.46.png

效果-骨骼

目前,閒魚的內部方案能夠很好地實現龍骨的動畫。正是因爲在子系統中保留了這樣的能力,所以如果未來有其他方案也可以按照ECS標準進行主流格式的實現。
屏幕快照 2020-06-22 下午2.13.13.png

效果-調試

值得一提的是因爲引擎和UI不分家,使得在調試工具的使用過程中能夠更好地看出遊戲或者動畫頁面的佈局情況,降低了調試工作的難度。

屏幕快照 2020-06-22 下午2.13.35.png

性能參考

基於Render層的設計使得我們享受到了Flutter引擎側對於Canvas的優化,也享受到了在Flutter Framework上局部刷新能力,因此無論是實現粒子還是實現骨骼的動畫,性能表現都非常不錯。
屏幕快照 2020-06-22 下午2.13.54.png

五、後續規劃和展望

回顧本文內容,首先爲大家分享了Flutter側在佈局方面的突破,Flutter這樣的開源框架具有足夠的能力能夠讓大家在其佈局側進行進一步深挖。此外,還和大家分享了閒魚在Flutter互動領域的突破,能夠很好地將UI和特效進行融合。第三個突破就是閒魚在Dart側的突破,將Dart語言實現了雲端開發和聯動,形成了邏輯後移的開發框架。而單點技術難以形成全面的合力,因此在後面與大家分享了將現有能力組合的情況產生不同的體系。假設將FaaS遠端的動態能力結合Nexus一體化能力、DX基於UI的表達能力,似乎就可以通過SSR寫完整的UI部分。同理,FaaS結合Candy也能夠實現互動編排的能力,將互動能力在FaaS端進行表達。
屏幕快照 2020-06-22 下午2.14.15.png

原文鏈接:https://developer.aliyun.com/article/765697?

版權聲明:本文中所有內容均屬於阿里雲開發者社區所有,任何媒體、網站或個人未經阿里雲開發者社區協議授權不得轉載、鏈接、轉貼或以其他方式複製發佈/發表。申請授權請郵件[email protected],已獲得阿里雲開發者社區協議授權的媒體、網站,在轉載使用時必須註明"稿件來源:阿里雲開發者社區,原文作者姓名",違者本社區將依法追究責任。 如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至:[email protected] 進行舉報,並提供相關證據,一經查實,本社區將立刻刪除涉嫌侵權內容。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章