2012年應屆畢業加入阿里巴巴,主導了閒魚基於Flutter的新混合架構,同時推動了Flutter在閒魚各業務線的落地。將來將持續關注終端技術的演變及趨勢git
Flutter是Google開源的跨端便攜UI工具包,除了具備很是優秀的跨端渲染一致性,還具有很是高效的研發體驗,豐富的開箱即用的UI組件,以及跟Native媲美的性能體驗。因爲它的衆多優點,也使得Flutter成爲了近些年來熱門的新技術。github
經過以上的特色能夠看出,Flutter能夠極大的加速客戶端的研發效率,與此同時獲得優秀的性能體驗,基於個人思考,Flutter會爲如下團隊帶來較大的收益:web
閒魚在以上的場景中屬於第一種場景,服務3億用戶的閒魚App的背後,開發資源投入不多,與競對相比,咱們是一隻再小不過的團隊,在這種場景下,Flutter爲閒魚業務的穩定發展以及提供更多的創新產品給予了很大的幫助。後端
但與此同時,Flutter在設計上帶來的優點同時又會帶來新的問題。全部的新技術都是脫胎於老技術的,Flutter也不例外,其身上帶有不少Chrome的影子。咱們再作一層簡化,若是咱們認爲Flutter是一個使用Dart語言的瀏覽器容器,請你們思考一下兩個問題如何解決。瀏覽器
帶着上面兩個問題,咱們來到閒魚場景下的具體Case以及解決方案的演進過程。緩存
在這種狀況下,閒魚須要考慮的是首先要考慮引入Flutter容器後的內存壓力,保證不要產生更多的內存溢出。與此同時咱們但願能讓Flutter和Native之間的頁面切換是順暢的,對不一樣技術棧之間的同窗透明。所以咱們有針對性的進行了屢次迭代。性能優化
在沒有任何改造的狀況下以iOS爲例,你能夠經過建立新的FlutterViewController來建立一個新的Flutter容器,這個方案下,當建立多個FlutterViewController時會同時在內存中建立多個Flutter Engine的Runtime(雖然底層Dart VM依然只有一個),這對內存消耗是至關大的,同時多個Flutter Engine的Runtime會形成每一個Runtime內的數據沒法直接共享,形成數據同步困難。架構
這種狀況下,閒魚選擇了全局共享同一個FlutterViewController的方式保證了內存佔用的最小化,同時經過基礎框架Flutter Boost提供了Native棧與Flutter棧的通訊與管理,保證了當Native打開或關閉一個新的Flutter頁面時,Dart側的Navigator也作到自動的打開或關閉一個新的Widget。目前Google官方的提供的方案上就是參考閒魚早先的這個版本進行的實現的。框架
然而在這種狀況下,若是出現如閒魚圖中所示多個Tab的場景下,整個堆棧邏輯就會產生混亂,所以閒魚在這個基礎上對Flutter Boost的方案進行了升級並開源,經過在Dart側提供一個BoostContainerManager的方式,提供了對多個Navigator的管理能力,若是打比方來看這件事,就至關於,針對Flutter的容器提供了一個相似WebView的OpenWindow的能力,每作一次OpenWindow的調用,就會產生一個新的Navigator,這樣開發者就能夠自由的選擇是在Navigator裏進行Push和Pop,仍是直接經過Flutter Boost新開一個Navigator進行獨立管理。工具
Flutter Boost目前已在github開源,因爲閒魚目前線上版本只支持Flutter 1.2的版本,所以須要支持1.5的同窗等稍等,咱們會在近期更新支持1.5的Flutter Boost版本。
因爲閒魚是一個閒置交易社區,所以圖片和視頻相對較多,對圖片視頻的線上性能以及內存佔用有較嚴格的要求。目前Flutter已提供的幾種方案中(Platform View以及Flutter Plugin),不管是對內存的佔用仍是整個的線上流暢度上還存在必定的問題,這就形成了當大部分同窗跟閒魚同樣實現一個複雜的圖文Feed推薦場景的時候,很是容易產生內存溢出。而實際上,閒魚在以上的場景下有針對性的作出了較大的優化。
在整個的Native UI到Flutter渲染引擎橋接的過程當中,咱們選用了Flutter Plugin中提供的FlutterTextureRegistry的能力,在去年上半年咱們優先針對視頻的場景進行了優化,優化的思路主要是針對Flutter Engine底層的外接紋理接口進行修改,將原有接口中必須傳入一個PixelBuffer的內存對象這一限制作了擴展,增長一個新的接口保證其能夠傳入一個GPU對象的TextureID。
如圖中所示,優化後的整個鏈路Flutter Engine能夠直接經過Native端已經生成好的TextureID進行Flutter側的渲染,這樣就將鏈路從Native側生成的TextureID->copy的內存對象PixelBuffer->生成新的TextureID->渲染,轉變爲Native側生成的TextureID->渲染。整個鏈路極大的縮短,保證了整個的渲染效率以及更小的內存消耗。閒魚在將這套方案上線後,又嘗試將該方案應用於圖片渲染的場景下,使得圖片的緩存,CDN優化,圖片裁切等方案與Native歸一,在享受已有集團中間件的性能優化的同時,也獲得了更小的內存消耗,方案落地後,內存溢出大幅減小。
目前該方案因爲須要配合Flutter Engine的修改,所以暫時沒法提供完整的方案至開源社區,咱們正在跟google積極溝通整個修改方案,相信在這一兩個月內會將試驗性的Engine Patch開源至社區,供有興趣的同窗參考。
將以上兩個問題解決之後,閒魚開始了Flutter在業務側的全面落地,然而很快又遇到新的問題,在多人協做過程當中:
在方案的前期,咱們使用了社區的Flutter Redux方案,因爲最早落地的詳情,發佈等頁面較爲複雜,所以咱們有針對性的對View進行了組件化的拆分,但因爲業務的複雜性,很快這套方案就出現了問題,對於單個頁面來講,State的屬性以及Reducer的數量都很是多,當產生新需求堆疊的時候,修改困難,容易產生線上問題。
針對以上的狀況,咱們進行了整個方案的第二個迭代,在原有Page的基礎上提供了Component的概念,使得每一個Component具有完整的Redux元素,保證了UI,邏輯,數據的完整隔離,每一個Component單元下代碼相對較少,易於維護和開發,但隨之而來的問題是,當頁面須要產生數據同步時,整個的複雜性飆升,在Page的維度上失去了統一狀態管理的優點。
在這種狀況下閒魚換個角度看端側的架構設計,咱們參考React Redux框架中的Connect的思想,移除掉在Component的Store,隨之而來的是新的Connector做爲Page和Component的數據聯通的橋樑,咱們基於此實現了Page State到Component State的轉換,以及Component State變化後對Page State的自動同步,從而保證了將複雜業務有效的拆解成子問題,同時享受到統一狀態管理的優點。與此同時基於新的框架,在統一了你們的開發標準的狀況下,新框架也在底層有針對性的提供了對長列表,多列表拼接等case下的一些性能優化,保證了每一位同窗在按照標準開發後,能夠獲得相對目前市面上其餘的Flutter業務框架相比更好的性能。
目前這套方案Fish Redux已經在github開源,目前支持1.5版本,感興趣的同窗能夠去github進行了解。
閒魚在去年經歷了業務的快速成長,在這個階段上,咱們同時進行了大量的Flutter的技術改造和升級,在嘗試新技術的同時,如何能保證線上的穩定,線下的有更多的時間進行新技術的嘗試和落地,咱們須要一些新的思路和工做方式上的改變。
以咱們平常工做爲例,Flutter的研發同窗,在每次開發完成後,須要在本地進行Flutter產物的編譯並上傳到遠端Repo,以便對Native同窗透明,保證平常的研發不受Flutter改造的干擾。在這個過程當中,Flutter側的業務開發同窗面臨着不少打包上傳更新同步等繁瑣的工做,一不當心就會出錯,後續的排查等讓Flutter前期的開發變成了開發5分鐘,打包測試2小時。同時Flutter到底有沒有解決研發效率快的問題,以及同窗們在落地過程當中有沒有Follow業務架構的標準,這一切都是未知的。
在痛定思痛之後,咱們認爲數據化+自動化是解決這些問題的一個較好的思路。所以咱們首先從源頭對代碼進行管控,經過commit,將代碼與後臺的需求以及bug一一關聯,對於不符合要求的commit信息,不容許進行代碼合併,從而保證了後續數據報表分析的數據源頭是健康的。
在完成代碼和任務關聯後,經過webhook就能夠比較輕鬆的完成後續的工做,將每次的commit有效的關聯到咱們的持續集成平臺的任務上來,經過閒魚CI工做平臺將平常打包自動化測試等流程變爲自動化的行爲,從而極大的減小了平常的工做。粗略統計下來,在去年自動化體系落地的過程當中單就自動打Flutter包上傳以及觸發最終的App打包這一流程就讓每位同窗天天節省一個小時以上的工做量,效果很是明顯。另外,基於代碼關聯需求的這套體系,能夠相對容易的構建後續的數據報表對整個過程和結果進行細化的分析,用數據驅動過程改進,保證新技術的落地過程的收益有理有據。
回顧一下上下文
除了本文說起的各類方案外,閒魚目前還在多個方向上發力,並對針對Flutter生態的將來進行持續的關注,分享幾個如今在作的事情
讓工程師去從事更多創造性的工做,是咱們一直努力的目標。閒魚團隊也會在新的一年更多的完善Flutter體系的建設,將更多已有的沉澱回饋給社區,幫助Flutter社區一塊兒健康成長。
本文爲雲棲社區原創內容,未經容許不得轉載。