目前在小程序互動場景下遇到的業務痛點,並且給出了基於Flutter引擎的解法。基於Flutter引擎,對外提供標準的Web Canvas API和並利用flutter渲染管線,讓業務代碼在小程序worker線程中直接渲染,縮短了渲染鏈路,提高了渲染性能。本次分享將由淘寶技術部無線開發專家萬紅波為大家分享目前在小程序互動場景下遇到的業務痛點,以及基於Flutter引擎的解法。
演講嘉賓簡介:萬紅波,花名遠湖,淘寶技術部無線開發專家。主要從事瀏覽器內核以及渲染引擎方向的研究。目前在AliFlutter團隊主要負責底層引擎以及Canvaa相關研究於應用。
以下內容根據演講視頻以及PPT整理而成。
觀看回放
本次分享主要圍繞以下六個方面:業務背景 業務痛點 解決方案 技術改造 業務效果 未來規劃
一、業務背景
小程序作為一個商業化解決方案,這幾年發展迅速,在頭部APP中佔據重要位置,與傳統H5同,渲染和邏輯分離到各自獨立線程,可以做到並行化。Worker和Render之間通過PostMessage或者SetData來通信。
二、業務痛點
小程序的架構可以滿足大部分場景,但在互動場景下,業務通常使用Canvas API進行每幀的繪製,每一幀通常包含大量的繪製操作,worker和render之間通信頻繁,渲染性能大幅度降低,用戶體驗較差。其中耗時較大的點在數據的多次序列化和反序列化且多次通過JNI來實現Java和C++的數據傳遞。在微信小程序和支付寶小程序文檔中,提供了一些最佳實踐來減低影響,比如PostMessage或者SetData的接口,一秒內調用不可超過20次,且對SetData的數據大小有所限制。但對於互動業務來說,要求每秒FPS的幀率,且每幀都需要大量的繪製指令需要傳遞,則很難通過這種方式解決。
三、解決方案
我們的解決方案是在小程序worker環境中直接對接渲染引擎,縮短渲染了鏈路,減少通信損耗,提高渲染性能。Worker中對接獨立的2D渲染引擎,不再通過render和worker傳遞消息。而其他的頁面,由於通信並不頻繁,仍使用原來的鏈路渲染。
我們選擇了Flutter引擎作為獨立的渲染引擎。我們選擇Flutter的原因:
1、跨平臺的特性,客戶端包含安卓和IOS,忽略客戶端細節,僅完成渲染,而Flutter引擎可以很好的屏蔽客戶端細節;
2、高性能,和傳統的H5渲染引擎相比,是一個輕量型的多線程2D引擎;
3、Flutter內部使用Skia作為渲染引擎,其兼容性、性能和適配性已在生產環境中被多次檢驗,安全穩定。
Flutter渲染管線較短,平臺層發出vsync信號,丟到Platform task,調用UI線程已註冊的callback,即Animator的BeginFrame函數,其將調用window的BeginFrame函數,window對象在Flutter中較為特殊,其連接上層Framework和下層Flutter engine。圖中綠色的區域即為Dart需要完成的事情,當BeginFrame進入Dart層之後,dart層調用Render的DrawFrame函數,做layout和paint,paint過程中圖片相關的部分會傳遞給IO線程抑或請求圖片解碼,同時在GPU線程上傳紋理。上述完成後,調用RenderFrame函數,實現上屏。其中Dart層的繪製指令被組織為Layer Tree這種數據結構,它後續被傳遞給GPU Task,GPU Task讀取Layer Tree中的渲染指令,直接光柵化,之後上屏。RenderFrame做下一次的vsync請求
最終方案:面向業務,提供標準的Web Canvas API,業務感知不到下層引擎變化;通過業務容器引入JS引擎,並把C++實現的Canvas API通過binging方式,注入到小程序worker線程;引入Canvas渲染管線,和原生dart模式共存,提高性能和內存使用率,業務可靈活切換。
四、技術改造
方案對渲染流水線有較大的改造,原先platform線程接收到vsync之後,將其傳遞給UI線程,UI線程在Dart層做繪製操作。而改造後在小程序環境中,用JS邏輯代替Dart層,業務邏輯在worker線程中完成,vsync被傳遞給JS線程,JS線程收到vsync後,驅動業務執行JS代碼,進行繪製並生成渲染指令生成後依然生成layer tree,傳遞給GPU線程,光柵化完成後上屏。
改造後的渲染管線,與改造前不同的是:platform線程收到vsync信號後,不再調用原先的callback,而是調用我們自己註冊的自定義callback,即OnVsync,將Vsync傳遞給JS線程。JS線程主要執行requestAnimationFrame的callback,對屏幕進行繪製更新,JS線程執行完成後,調用FlushFrame,將layer tree傳遞給GPU線程,直接光柵化後上屏。繪製結束後,通過Animator的RequestFrame函數請求下一次vsync。
圖片加載流程改造,原先的圖片加載流程並不適用小程序環境下,JS線程中的資源請求被丟給平臺的手淘圖片庫,完成圖片的下載和解碼,解碼後的數據傳遞給IO線程。IO線程生成GPU紋理,並將其緩存在Flutter engine中。業務直接使用引擎中已經生成紋理的圖片,可直接上屏。
五、業務效果
安卓低端機上,業務改造前FPS為15,改造後42,效果明顯。FPS數據由於測試業務沒有通過Vsync來驅動繪製,而是直接使用timer來驅動,使得CPU佔用率較高,且改造後FPS提高很大。線下測試中,採用Vsync驅動繪製,改造後的FPS提高30%左右。
目前我們還支持Lottie動畫,設計師可以通過Lottie動畫設計畫面效果。並且支持白鷺遊戲引擎。
六、未來規劃
未來規劃有三個方向,首先接入更多三方遊戲引擎,和三方遊戲引擎深度合作,其次探索高階渲染API的實現。支持WebGL API。第三探索獨立小遊戲容器,能夠基於已完成的方案做更多的嘗試。
關注「淘系技術」微信公眾號,一個有溫度有內容的技術社區~