重度使用Flutter研發模式下的頁面性能優化實踐

簡介: 淘寶特價版是集團內應用Flutter技術場景比較多,且用戶量一億人以上的應用了。目前咱們首頁、詳情、店鋪、個人,看看短視頻,及評價,設置等二級頁面都在用Flutter技術搭建。一旦Flutter有性能瓶頸,重度使用Flutter研發的咱們該如何作到性能優化?
image.png緩存

做者 | 餘玠
來源 | 阿里技術公衆號性能優化

一 Flutter頁面性能優化的挑戰

淘寶特價版是集團內應用Flutter技術場景比較多,且用戶量一億人以上的應用了。目前咱們首頁、詳情、店鋪、個人,看看短視頻,及評價,設置等二級頁面都在用Flutter技術搭建。多線程

咱們發現使用Flutter常常會遇到性能問題。由於Flutter嚴格意義上僅是一種「UI渲染框架」,它經過異步來來實現子線程渲染UI,而且經過Skia保證兩端「渲染的一致性」。但子線程執行並渲染,且動態庫打包這些策略並不是「一片通吃」,會致使損耗頁面打開性能及可交互時長的增長。試想,app啓動時動態庫加載的dynamic binding(影響啓動時長),頁面啓動時主線程啓動了頁面,但ui渲染卻須要等待Flutter的子線程執行並渲染,低端機上頁面會短暫白屏(頁面未渲染影響可交互時長,雖然fps欺騙性的提升了)。app

Flutter有性能瓶頸,但重度使用Flutter研發的咱們是如何作到性能優化的?本篇會就基礎鏈路各Flutter頁面的優化策略,分享咱們的實踐!框架

二 模塊級混合——首頁的優化實踐

首頁最開始是所有采用Flutter+DXFlutter(面向Flutter的UI動態化框架)實現,業務實現一切ok,但發版的時候測試同窗發現首頁的啓動性能忽然比上個版本跌了1s。這個問題是必然的,由於Flutter是動態庫要延遲加載和綁定,同時DXFlutter大量的模板邏輯也會極大消耗性能。異步

問題很難解,當時咱們就是否繼續所有Flutter,但優化引擎和DXFlutter,仍是回退爲Native實現產生了分歧。若是回退Native,則首頁及搜索的分類tab技術方案都要切回native,成本巨大。最終,咱們根據特價版的現狀及經驗,拍板採用:app啓動時首頁推薦等採用Native實現,但搜索實現的其餘tab分類繼續採用Flutter,如此不會對搜索業務研發模式產生影響,又能避免Flutter帶來啓動性能的損耗。組件化

可是該方案會遇到一個技術挑戰:咱們使用的Flutter混合棧FlutterBoost僅支持頁面級混合,還不支持頁面內模塊級混合。由於Flutter是單window的設計策略,若是模塊級混合必然會遇到Flutter頁面生命週期的管理及渲染窗口尺寸的一致性問題。佈局

前一個問題是因Flutter是單引擎引發的。當模塊切換的時候,新模塊顯示須要鏈接引擎從新觸發渲染,不然頁面會空白或不可交互。這個在FlutterBoost中早就作了。性能

後一個問題是單window,Flutter頁面上彈框Native頁面都會致使頁面佈局問題。測試

但模塊級混合明顯是技術可行的,咱們在AliFlutter正物、來一等同窗的參與下,很快就開發出了能夠容納Native、Flutter甚至其餘類型如WebView的模塊級混合容器。以下圖:

image.png

咱們經過一個FlutterWrapperVC,基於FlutterBoost解決單引擎渲染問題,根據模塊可見性切換FlutterEngine和虛擬機,保證當前可見的模塊能正常渲染,並執行底層的Flutter代碼;而後經過Window大小強制修正解決了單window問題,解決佈局問題。最後咱們也考慮到了模塊複用性,將這個能力組件化,並封裝到這裏:LTaoUIKit。

pod LTaoUIKit '0.0.3.89'
基於這個方案以後,這麼改造後,首頁的啓動實踐至少提高1s。更重要的是首頁的研發就如圍棋裏建了兩眼,活出了一片。後面推薦頁基於native dxcontainer實現後,就直接能夠複用以前淘寶等成熟app的優化經驗。

後面咱們優化RT,DX模板打底,圖標本地化,圖片壓縮多管其下,首頁啓動性能穩穩提高。

同過後面對首頁的啓動鏈路作了分步治理,並作了較爲體系化的治理建設:

image.png

三 數據預取與FFI——純Flutter頁面的優化實踐

上面探討模塊混合Flutter頁性能優化,本節則講整個頁面均是Flutter實現的優化策略,這應該也是大部分Flutter開發者常遇到的。經過這種方式,以特價版詳情頁爲例,咱們在以前的優化結果上又再優化了100多ms,如下是具體數據:

Android(vivo y67): 80~100ms
iOS(iPhone6): 120~200ms

首先,Flutter頁面會遇到哪些性能瓶頸?從Flutter機制看,他實際上是個能較好解決「多端一致問題」的「UI渲染框架」,雖然提供了經過bridge訪問native,但Flutter bridge性能極差,涉及到了線程切換,字符編碼等問題(後面會講)。因此,咱們使用Flutter應該避免直接經過Flutter來解決IO等資源訪問的工做,並且這些工做應儘可能放在native側。

顯然app一張頁面的啓動,每每涉及到請求服務端準備渲染數據。同時,從路由跳轉,到經過Engine初始化Native的VC或者activity到Engine構造Rasterrizer還涉及Engine層面的線程等待。這些時間其實能夠作很多事情,咱們能夠將服務端數據請求放在這個階段,這就是咱們但願作的「數據預取」。

其實「數據預取」在淘寶上已經大規模用了,但在Flutter頁面上所顯示的優越性則會更強,由於Flutter頁的多線程切換太多了,很容易就掉入channel bridge的陷阱。如咱們詳情頁最開始也用了數據預取,但數據預取調用是從Flutter發起的,性能彷佛有提高,但並不那麼明顯。爲何?如下是從Flutter發起一個mtop請求的流程圖,能夠從其中一窺究竟:

image.png

上圖UI線程是指Flutter的ui線程,並不是系統主線程。請求從「開始」處開始,兜兜轉轉,要經歷2次線程切換等待,屢次的數據encode和decode,形成的性能損耗仍是蠻多的,分析以下:

  • 首先,一旦某個情形下設備cpu緊張,則Flutter的請求/數據返回會遲遲沒法送達到native或者Flutter。
  • 其次,當數據量大的情形下,數據encode和decode也會耗費更多時間。
  • 最後,頁面打開常常遇到Engine和Native之間誰先啓動的問題。好比VC啓動了,這個時候並不能立刻就給Flutter發送message,由於Flutter Engine可能尚未準備好,此時message丟失,雙方都不知道。這個問題在FlutterBoost中遇到很多。

咱們最終經過如下策略來解決:

  • 數據預取在Native側發起,在頁面路由構造Native VC/Activity時,就立刻發起mtop等請求。
  • mtop返回的數據優先不經過channel bridge返回給Flutter層,而是經過ffi機制供Flutter直接讀取。
  • 上面native側必須暫存數據,但爲避免長久引用形成資源泄漏,採用LRU策略緩存數據(iOS不能用NSCache,猜猜爲何)。
  • 考慮到有些頁面數據能夠持久化存儲,供下次使用,咱們構造了多級緩存策略。
  • 將上面能力所有組件化,以供其餘業務複用。

詳細的設計以下:

首先,基於ffi和native側數據預取,優化後的數據請求鏈路以下:

image.png

右上角之因此還有channel bridge是爲解決Native請求返回慢於Flutter頁面渲染的情形下的數據刷新。

其次,咱們構建了多級緩存策略和緩存失效及複用策略,以支持部分頁面數據的持久化複用提高首屏渲染性能:

image.png

以緩存複用策略爲例,咱們支持如下策略:

  • 激進型:第二次請求直接使用上一次緩存數據,再也不立刻刷新數據,待緩存天然過時後刷新。該策略適用於頁面數據不常變的情形。
  • 正常型:第二次請求可以使用上一次緩存,但仍需請求並立刻刷新數據。該策略比較普適,適合數據變化不頻繁的情形。
  • 保守型:第二次請求不可以使用上一次緩存,需請求最新數據。適合強實時性的頁面數據渲染。

最後,咱們將這些能力作了封裝,好比iOS側,咱們以單獨的SDK集成:

pod LTPrefetch '1.0.1.19'
目前基礎鏈路如詳情,個人,店鋪,mini詳情等都採用了這個方案進行優化,啓動實踐均有了不錯的提高。

四 其餘優化實踐

其餘還有不少優化實踐。有些是淘系已經實踐過的,有些是特價版根據Flutter的特色有所改動的。這裏不詳細說了,僅就咱們使用過的列個列表:

  • 詳情從首頁借圖。
  • 資源壓縮及本地預置:如首頁dx模板預置,Json壓縮及預置,圖片壓縮及預置。
  • 數據提早異步加載。如個人頁面數據,其實在用戶登錄的時候就會異步加載並緩存下來,而後經過上面的緩存更新策略來更新。
  • 優化服務端RT,精簡協議。
  • 其餘。

五 最後

其實咱們的優化策略更多在上層應用上作了優化,UC那邊在Flutter Engine層面作了優化,後期能夠考慮使用他們引擎,相信頁面打開性能會更上一層樓。

同時上面的ffi及數據預取也能夠作的更激進一些。如經過Dart2Native的方式,徹底實現Json數據的encode和decode本地實現,容器訪問的本地實現,估計還能提高至少50ms的時間。
原文連接

本文爲阿里雲原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索