Pluto - iOS 上一个高性能的排版渲染引擎
Pluto 是 iOS 上的一個排版渲染引擎,通過 JSON/JS 文件可以很方便地描述界面元素,開發效率很高,并且在流暢度,內存等方便有保證。pluto.oa.com 上有更多詳細資料。
Qzone Feed 業務復雜,樣式很多。每次新增一種 Feed 樣式,開發工作量很大,需要跟版本。樣式之間耦合嚴重,每改一種樣式,另一種樣式可能會受影響。
?
基于這樣的背景下,Feed Team 急需一個比較成熟的渲染引擎,他至少需要解決以下問題:
1、提升開發效率。
2、樣式之間獨立,不互相耦合。
3、新增和修改 Feed 樣式不需要跟版本。
4、無論采取什么方案,列表的滑動流暢度必需保證至少跟現有的一樣。
基于這樣的需求,我們重新盤點了市面上比較成熟的排版渲染引擎 ComponentKit,新的開發框架比如 React Native,甚至參考 Android 的排版系統。都難以同時解決上述問題,最終決定我們自己來做一個,一個專注性能和開發效率的排版引擎,Pluto。目前 Pluto 已經應用于 QQ,Qzone 上大部分的空間 Feed 樣式,關于 Pluto 和這些現有的排版渲染引擎對比的細節,我后面會說明,我們先來看看 Pluto 用起來是怎么樣的。
首先需要一個排版描述:
?
以上排版數據的結果如下,左邊是一個圖片控件,右邊是文字控件。
?
想必看到這個 demo,大家應該知道 Pluto 是什么東西了。上面的 JSON 文件閱讀起來也非常自然,直接。接下來要解決的問題比較多。這里重點描述點擊事件、模板、重用、擴展。分別解決熱更新,開發效率,性能優化、功能擴充,四個方面的問題。
點擊事件
Pluto 還可以通過 json 描述綁定事件響應的 js 腳本,比如以下 json 文件:
?
圖片組件被點擊的時候,可以找到相應的 js 文件,調用 onClick 方法。
模版
一開始的例子中,使用一個 JSON 表達了一個 UI 排版,假如有很多類似的界面元素同時存在,就有很多重復數據的 JSON 文件。這個時候就需要模版特性。比如列表中的每個 Cell,都共享同一個模版,只是填充的數據不一樣。以下例子中,將 "imageName" 替換成"${image}",而不是一個具體的圖片。然后提供一個字典映射,每一個數據項映射不同的數據,產生不同的視圖。
?
重用
重用是 Pluto 在設計之初就比較重點考慮的一個因素,也是不同于其他引擎的最大的特色。可以說有了這個特性,才能應用在列表等有高性能要求的場景。重用指的是,在 UITableView 等列表控件,在滑動的時候,不同列表項復用同一個 Cell,Cell 里面的視圖數據可以重復使用,核心是為了減少創建視圖和修改視圖樹的次數。值得強調的是,Pluto 里面對視圖的重用優化,是已經內置的功能,調用方不需要額外操作。
實現原理如下圖所示,每個 Pluto 生成的視圖中,會包含一個復用池,當使用復用特性時,視圖不會被銷毀,而是被回收,回收時,其子視圖會被放入復用池內,(這里的子視圖是一個視圖樹,即也包含了子視圖的子視圖)并隱藏起來。復用時,就只需恢復顯示,調整寬高,數據等,比創建視圖的成本低很多。
?
擴展
Pluto 內置了一些渲染控件,比如 文字(TextItem),圖片(ImageItem),按鈕(ButtonItem)。如果這些組件不滿足需求,還可以通過擴展組件來完成封裝。實現自定義控件的大概流程如下:
?
在 demo 里面有演示,包含了實現一個自定義視圖的更多細節。
特點分析
這里梳理一下 Pluto 的一些特點。
快速:Pluto 的排版性能與直接書寫的排版代碼性能相差不大。目前在手機 QQ 上跟其他列表相比,流暢度領先。(當然,比 Auto Layout 性能好很多)異步:Pluto 的整個排版,文字渲染流程,都是可以在工作線程執行的,并且線程安全。不會影響用戶操作。
描述型排版:Pluto 接收的排版信息是一個字典,二手手機號碼買賣平臺描述型的表達排版信息,不需要寫邏輯代碼。做成描述型的好處是:
● 方便維護,不易出錯(因為不包含代碼)。
● 方便緩存。
● 可以是寫成 JSON 格式,通過本地讀取,或者后臺下發來排版。
● 不可變數據: 在整個排版引擎中,排版數據是不可變的,這意味著很容易維護、測試、緩存、復用以及做到線程安全等等。
緩存和復用:由于排版數據是不可變的,所以內部會進行緩存,這樣可以加快整個顯示流程。渲染部分則會盡量復用已存在的控件,加快渲染。同時同一個視圖的排版數據更新,也會內部做差異化對比,排版流程中也會盡可能地復用舊的排版信息。
模版體系:Pluto 有完整的模版功能。同樣的樣式只需要書寫一次,形成模版,然后根據情況往模版填充不同的數據,可以生成不同的視圖。模版之間也可以通過組合來復用。
圖文混排:Pluto 支持基礎控件的混排,比如 Text 標簽,Image 標簽,也支持自定義標簽和自定義控件。
對比分析
在對比分析之前,我們先 review 一下 Pluto 的使用主場景:一個可以無限加載更多 Feed 的 Feed 列表,要求內存,CPU,流暢度都有不錯的表現。
針對這個場景,對比分析現有主流的界面開發庫,分別是 Xcode 自帶的 Storyboard/Xib,Facebook 主導的開源組件 ReactNative、ComponentKit,以及本文的 Pluto。
● storyboard 是一個可視化的 UI 編輯工具,開發效率比較高。性能上,控件都使用了原生控件,所以性能會差一些。也不支持異步排版,影響流暢度。生成的文件是使用 XML 描述,理論上是可以動態下發,但是 XML 格式不公開,各個版本也不保證兼容,所以比較難做到動態下發。
● React Native 使用 JS+HTML 的方式進行開發,開發效率很高。也有很高的動態性和跨平臺特性。但是性能比較捉急,在速度上,內存使用上有一些問題,很難在 Feed 流這種性能要求比較高的地方。
● ComponentKit 跟 Pluto 其實很類似,區別最大的地方在于 Component 不支持 JSON/XML 這種靜態表達樣式的功能,以及事件動態綁定的功能。在動態性和可維護性方面,會弱很多。我們有思考過在 ComponentKit 的基礎上增加 JSON 表達樣式的功能。但是 ComponentKit 直接使用了原生視圖,并沒有一個中間的虛擬視圖層,所以性能上也是問題。改造成本太高。
● Pluto 相比 React Native 來說,組件不夠豐富,使用 JSON 可以讓開發效率在描述排版方面接近 React Native;性能相比其他組件來說很不錯;支持異步保證了主線程的流暢度;動態性跟 React Native 一樣,不能新增控件,控件都是本地預埋。比較依賴本地代碼的邏輯,不能修改本地代碼的已有邏輯,但是可以替換一部分。當然,邏輯只能預埋的話,也不會有審核風險。
梳理表格如下:
via:
總結
以上是生活随笔為你收集整理的Pluto - iOS 上一个高性能的排版渲染引擎的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 真良心大厂EPIC,页游广告又有新素材了
- 下一篇: 如何做好游戏内实时语音体验