Graver 是一款高效的 UI 渲染框架,它以更低的資源消耗來構建十分流暢的 UI 界面。Graver 首創性的採用了基於繪製的視覺元素分解方式來構建界面,得益於此,該框架能讓 UI 渲染過程變得更加簡單、靈活。目前,該框架已經在美團 App 的外賣頻道、獨立外賣 App 核心業務場景的大多數業務中進行了應用,同時也獲得美團外賣內部技術團隊的承認和確定。html
App 渲染性能優化是一個廣泛存在的問題,爲了惠及更多的前端開發同窗,美團外賣 iOS 開發團隊將其進行開源,Github 項目地址與使用文檔詳見:https://github.com/Meituan-Di... 。咱們但願該框架可以應用到更廣闊的業務場景。固然,咱們也知道該框架尚有待完善之處,也但願能與更多技術同行一塊兒交流、探討、共建。前端
咱們爲何須要關注界面的渲染性能?App 使用體驗主要包含產品功能、交互視覺、前端性能,而使用體驗的好與壞,直接影響用戶持續使用仍是轉而使用其餘 App,因此咱們很是關注 App 的渲染性能。並且在互聯網產品流量競爭愈發激烈的大背景下,優質的使用體驗能夠爲現有用戶提供更好的服務,進而提升用戶轉化和留存,這也意味着創收、盈利。git
<center><font color=gray size = 2>圖1 使用體驗與轉化、留存</font></center>github
美團外賣 App 從2013年成立至今,已經走過了五個春秋,在技術層面前後經歷了快速驗證、模塊化、精細化和平臺化四個階段,產品形態上也日趨成熟。在此期間,咱們構建並完善了監控、報警、容災、備份等各項基礎設施,Metrics 便是其中的性能監控系統。編程
曾經一段時間,咱們之外賣 App 首頁商家卡片列表爲例,經過 Metrics 性能監控系統發現其在 FPS、CPU、Memory 等方面的各項指標並不理想。因而,經過 Xcode 自帶的 TimeProfile 等性能檢測工具,而後結合代碼分析等手段找到了現存性能瓶頸。與此同時,咱們梳理其近半年的迭代版本需求發現,UI 每每須要根據不一樣場景甚至不一樣用戶展現不一樣的內容。爲了避免斷迎合用戶的需求,快速應對市場變化,這種特徵還會持續存在。然而,它會帶來如下問題:後端
<center><font color=gray size = 2>圖2 影響渲染性能、研發效率的瓶頸點</font></center>緩存
爲了解決現存的性能瓶頸以及後續潛在的性能瓶頸,咱們指望構建一套解決方案,該方案能在充分知足外賣業務特徵的前提下,以標準化、一站式的方式解決 iOS 端 App 的渲染性能問題,而且對研發效率有必定提高, Graver(雕工)框架應運而生。安全
由於 Graver 首創性地採用了全新的視覺元素分解思路,因此該框架使用起來十分靈活、簡單。咱們先來看一下 Graver 的主要特色:性能優化
性能表現優異網絡
之外賣 App 首頁商家列表爲例,應用 Graver 以後5分位滾動幀率從滿幀的<font color=red size = 2>84%</font>提高至<font color=red size = 2>96%</font>,50分位幾乎滿幀;CPU 佔用率降低了近<font color=red size = 2>6個百分點</font>,有效提高了空閒 CPU 的資源利用率,下降了峯值 CPU 的佔用率。如圖3所示:
<center><font color=gray size = 2>圖3 優化先後技術指標對比</font></center>
「一站式」異步化
Graver 從文本計算、樣式排版渲染、圖片解碼,再到繪製,實現了全程異步化,而且是線程安全的。使用 Graver 能夠一站式得到所有性能優化點,可讓咱們:
性能消耗的「邊際成本」幾乎爲零
Graver 渲染整個過程除畫板視圖外徹底沒有使用 UIKit 控件,最終產出的結果是一張位圖(Bitmap),視圖層級、數量大幅下降。之外賣 App 首頁鉑金展位視圖爲例,原有方案由58個控件、12層級拼接而成;而應用 Graver 後僅需1個視圖、1級層級繪製而成。 伴隨着需求迭代、視覺元素變化,性能消耗恆屬常數級。如圖4所示:
<center><font color=gray size = 2>圖4 外賣 App 鉑金展位應用 Graver 先後對比</font></center>
渲染速度快
Graver 併發進行多個畫板視圖的渲染、顯示工做。得益於圖文混排技術的應用,達到了內存佔用低,渲染速度快的效果。因爲排版數據是不變的,因此內部會進行緩存、複用,這又進一步促進了總體渲染效率。Graver 既作到了高效渲染,又保證了低時延頁面加載。
<center><font color=gray size = 2>圖5 渲染效率說明</font></center>
以「少」勝「繁」
Graver 從新抽象封裝 CoreText、CoreGraphic 等系統基礎能力,經過少許系統標準圖形繪製接口便可實現複雜界面展現。
基於位圖(Bitmap)的輕量事件交互系統
如上述所說,界面展現從傳統的視圖樹轉變爲一張位圖,而位圖不能響應、區份內部具體位置的點擊事件。Graver 提供了基於位圖的輕量事件交互系統,能夠準確識別點擊位置發生在位圖的哪一塊「繪製單元」內。該「繪製單元」能夠理解爲與咱們一向使用的某個具體 UI 控件相對應的視覺展現。使用 Graver 爲某一視覺展現添加事件如同使用系統 UIButton 添加事件同樣簡單。
全新的視覺元素分解思路
Graver 一改界面編程思路,與傳統的經過控件「拼接」、「添加」,視圖排列組合方式構建界面不一樣,它提供了靈活、便捷的接口讓咱們以「視覺所見」的方式構建界面。這一特色在下文Graver使用中詳細闡述,正是由於該特色實現了研發效率的提高。
Graver 引入了全新的視覺元素分解的思路。藉助該思路能夠實現經過一種對象來表達任一視覺元素、甚至是任一視覺元素的組合,從而消除界面佈局的複雜性。
咱們先來回顧下傳統界面的構建方式,之外賣 App 商家卡片其中一種樣式爲例,如圖6所示:
<center><font color=gray size = 2>圖6 外賣 App 商家卡片</font></center>
在實現商家卡片的界面樣式時,一般會根據視覺上的識別、交互要求來創建界面展現與系統提供的 UI 控件間的映射關係。以標號②位置的樣式爲例,在考慮複用的狀況下一般這部分會使用三個系統控件來完成,分別是左側藍底的「預訂」使用 UILabel 控件、右側的藍色邊框「2.26.21:30起送」使用 UILabel 控件、把左右兩側 UILabel 控件裝起來的 UIView 控件;在肯定好採用的 UI 控件以後,須要針對展現樣式分門別類的設置各個控件的渲染屬性來實現圖示 UI 效果,渲染屬性一般一部分預設,一部分根據業務數據的不一樣再進行二次設置;其次,設置各個控件的內容屬性實現業務數據內容的展現,展現的內容通常是網絡業務數據經邏輯處理、加工後的數據。若是涉及到點擊事件,還須要添加手勢或者更換成 UIButton 控件。接下來,須要根據視覺要求實現排版邏輯,以標號⑧、⑨爲例,當標號⑧位置的數據沒有的狀況下,須要上提標號⑨位置的「美團專送」到圖示標號⑧位置。諸如相似的排版邏輯隨處可見。對於圖示任一位置的展現內容都存在上述的循環思考、編寫工做。隨着界面元素的增長、變化,問題會變得更加複雜。
傳統的界面構建方式實際上是在 UI控件的維度去分解視覺元素,具體是作如下四方面的編寫工做:
最後,將各個控件以排列組合方式合成爲一棵視圖樹。
Graver 框架提供了以畫板視圖爲基礎,經過對更底層的 CoreText、CoreGraphic 框架封裝,以更貼近「視覺所見」的角度定義了全新視覺元素分解、界面展現構建的過程。
一般「視覺所見」可劃分爲兩部分:靜態展現、動態展現。靜態展現包含圖片、文本;動態展現包含視頻、動畫等。在視覺展現所有爲靜態內容的時候,一個 Cell 便是一個畫布,除此之外沒有任何 UI 控件;不然,能夠按需靈活的進行畫布拆分來知足動畫、視頻等須要。
<center><font color=gray size = 2>圖7 畫板和傳統視圖樹</font></center>
以圖6商家卡片中標號②、⑧爲例,新實現方式的僞代碼是這樣的:
WMMutableAttributedItem *item = [[WMMutableAttributedItem alloc] init];
[[[[item appendImage:[[UIImage wmg_imageWithColor:"blue"] wmg_drawText:"預訂"]] appendImage:[[UIImage wmg_imageWithColor:"clear" borderWidth:1 borderColor:"blue"] wmg_drawText:"2.26.21:30起送"] appendWhiteSpaceWithWidth:"width"]//整體寬度減去②和⑧的寬度總和剩餘部分 apendText:"50分鐘|2.5km"];
上述實現方式便是把標號②、⑧部分做爲一個總體來實現,任何單一系統控件都沒法作到這一點。
<center><font color=gray size = 2>圖8 Graver 工做時序</font></center>
如圖8所示,Graver 涉及多個隊列間的交互,之外賣 App 商家列表爲例,總體流程以下:
總體按照隊列間串行、隊列內並行的方式執行。
Graver 在外賣內部發布以後,咱們也將其推廣到更多的業務線,並但願 Graver 可以成爲對業務開展有重要保障的一項基礎服務。通過半年多的內部試用,Graver 的可靠性、渲染性能、業務適應能力也受到外賣內部的確定和承認。截止發稿時,Graver 已經基本覆蓋了美團 App 的外賣頻道、獨立外賣 App 核心業務場景的大多數業務。下面列舉 Graver 在外賣業務的部分應用案例:
總結一下,對於界面渲染性能優化而言,要站在一個更高角度來思考問題的解決方案。橫向上,從普適性角度解決性能瓶頸點,避免其餘人遇到相似問題的重複工做;縱向上,從長遠考慮問題作到防微杜漸,一次優化,長期受益。基於此,咱們提出一站式、標準化的渲染性能解決方案。誠然,這會遇到不少難點。面對界面樣式構建的問題,系統 UIKit 框架着實爲咱們提供了便利,然而有時候咱們須要跳出固有思惟,嘗試創建一套全新界面構建、視覺元素分解的思路。
洋洋,美團高級工程師。2018年加入美團,目前負責【美團外賣】和【美團外賣頻道】的 iOS 客戶端首頁業務,以及支撐首頁業務的技術架構、工具和系統的開發和維護工做。
美團外賣長期招聘 Android、iOS、FE 高級/資深工程師和技術專家,Base 北京、上海、成都,歡迎有興趣的同窗投遞簡歷到chenhang03#meituan.com。