做者:Wison,腾讯移动客户端开发 高级工程师
商业转载请联系腾讯WeTest得到受权,非商业转载请注明出处。
原文连接:http://wetest.qq.com/lab/view/369.htmlhtml
Pluto 是 iOS 上的一个排版渲染引擎,经过 JSON/JS 文件能够很方便地描述界面元素,开发效率很高,而且在流畅度,内存等方便有保证。ios
Qzone Feed 业务复杂,样式不少。每次新增一种 Feed 样式,开发工做量很大,须要跟版本。样式之间耦合严重,每改一种样式,另外一种样式可能会受影响。json
基于这样的背景下,Feed Team 急需一个比较成熟的渲染引擎,他至少须要解决如下问题:缓存
一、提高开发效率。安全
二、样式之间独立,不互相耦合。性能优化
三、新增和修改 Feed 样式不须要跟版本。框架
四、不管采起什么方案,列表的滑动流畅度必需保证至少跟现有的同样。异步
基于这样的需求,咱们从新盘点了市面上比较成熟的排版渲染引擎 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 同样,不能新增控件,控件都是本地预埋。比较依赖本地代码的逻辑,不能修改本地代码的已有逻辑,可是能够替换一部分。固然,逻辑只能预埋的话,也不会有审核风险。
梳理表格以下:
腾讯WeTest iOS预审工具
为了提升IEG苹果审核经过率,腾讯专门成立了苹果审核测试团队,打造出iOS预审工具这款产品。通过1年半的内部运营,腾讯内部应用的iOS审核经过率从平均35%提高到90%+。
现将腾讯内部产品的过审经验,以线上工具的形式共享给各位。在WeTest腾讯质量开放平台上能够在线使用。点击 http://wetest.qq.com/product/ios 便可当即体验!
若是使用当中有任何疑问,欢迎联系腾讯WeTest企业QQ:800024531