Categories
程式開發

挖掘低端机性能极限:优酷iPhone首页性能优化


一、背景

优酷 iPhone 端还有很多低端机用户,为进一步提升用户体验和用户活跃度,优酷主客团队启动了 iPhone 首页频道页性能优化项目,主要包括架构优化和 UI 渲染优化。

本文主要介绍渲染优化部分的技术经验。渲染优化主要采用了异步渲染和对象预缓存方式,整体效果较好。

二、优酷首页性能现状

优酷 iPhone 首页频道页经过架构改造、新视觉改版、业务迭代,积累了较多的性能压力,新视觉改版大量使用了圆角、阴影、渐变等性能消耗较大的 UI 样式,首页滑动性能有所下降,通过 Instrument 测得 iPhone6 plus 上首页帧率平均 44 帧左右,用户体验尚不理想。

  1. 性能问题分析

1)耗时方法分析

在首页滑动时,主要调用的是相关 cell 的 query view、reuse view 方法,打印相关方法的主线程耗时可以发现,query view 方法耗时一般不高,但在没有可重用 cell 需要新建时耗时会增高很多,导致明显的卡顿。

挖掘低端机性能极限:优酷iPhone首页性能优化 1

iPhone6 plus 优酷首页 query view 方法主线程耗时

reuse view 方法平均每个坑位耗时 3 毫秒左右,而一个组件往往包含多个坑位,总体耗时超过 10ms,造成滑动掉帧。

挖掘低端机性能极限:优酷iPhone首页性能优化 2

iPhone6 plus 优酷首页 reuse view 方法主线程耗时

2)UI 卡片代码分析

现有 UI 卡片的代码主要分为三个部分:初始化、绑定数据、事件处理。其中对滑动帧率影响较大的主要是初始化和绑定数据部分,也对应于上面 query view 和 reuse view 方法的耗时。 UI 卡片需要在主线程创建,分配内存、初始化等操作耗时较大,尤其控件较多时新建卡片易造成主线程卡顿;卡片重用池稳定时不再新建卡片,此时性能主要消耗在卡片 reuse 绑定数据时,布局变换、文本 size 计算、图层混合、图片文本渲染等高耗性能操作是造成卡顿的主要原因,从上面 Instrument 测试结果看,CPU 占用时有达到甚至超过 100%的情况,GPU 占用最高 76% 左右,必须降低 CPU、GPU 占用。

挖掘低端机性能极限:优酷iPhone首页性能优化 3

优化前卡片复用时序

  1. 性能解决方案

对于卡片初始化的耗时可以通过预创建卡片的方式优化,在启动后闲时创建页面主要卡片并缓存备用,以减少滑动过程中创建新卡片。

对于卡片复用时的高耗性能操作,通过简化 UI 代码、文本高度预计算、改用 Layer 渲染、减少图层混合等方式优化后,首页低端机帧率已由 38.4 帧提升到 45 帧左右,提升 15%,但效果还不够理想,滑动卡顿、掉帧还比较明显,CPU 占用峰值在低端机上依然达到 100%,说明复用任务即使优化后也已达到 CPU 性能极限,此时继续在主线程上优化效果不大,可以采用子线程复用结合异步渲染的方式,将复用任务分拆到子线程当中,减少主线程拥塞。为此我们开发了 ModelUI 渲染框架以实现相关性能优化方案。

三、ModelUI 渲染框架

  1. ModelUI 简介

Model 渲染框架主要包含三个部分:

1)线程安全的 UI Model 层

由于系统 UIKit 只能在主线程操作,为了实现子线程拆分等,ModelUI 仿照 UIKit 抽象了线程安全的 UI Model,如 LabelModel 、 ImageModel 等,以封装渲染参数、渲染内容,供 ModelContainer 管理、渲染,UI Model 提供了统一的类似 UIKit 的使用接口,并对齐了优酷在 UIKit 的相关扩展方法,不影响现有开发习惯,也方便迁移现有 UI 卡片,大幅减少了迁移工作。

2)四种渲染方式

挖掘低端机性能极限:优酷iPhone首页性能优化 4

iOS 绘制渲染框架图

iOS 系统在底层硬件之上提供了三层渲染 API,分别封装为 CoreGraphics、QuartzCore(CoreAnimation、LayerKit)和 UIKit 三个库,其他常见的第三方 UI 库主要是 YYKit、 AsyncDisplayKit(Texture),YYKit 对 UIKit 部分控件进行了优化,AsyncDisplayKit 是 Facebook 基于 CoreGraphics 开发的异步渲染框架,几种渲染方式对比如下:

挖掘低端机性能极限:优酷iPhone首页性能优化 5

四种渲染方式各有短长,为满足不同业务需求,ModelUI 提供了四种渲染方式:已被广泛使用的 UIKit 渲染,能力完善且性能有所改善的 YYKit 渲染,支持动画性能较好的 Layer 渲染,以及性能最优的异步渲染,其中由于 AsyncDisplayKit 过重,侵入比较大,ModelUI 开发了自己的轻量级异步渲染,以更好的配合 UI Model 使用。

每个 UI Model 默认使用异步渲染,但异步渲染无法添加交互动画,不能响应点击事件,对于需要交互动画但不需响应事件的 UI Model 可使用 Layer 渲染,对于两者都需要的 UI Model 可使用 YYKit 或 UIKit 渲染。ModelUI 支持不同渲染方式混合使用,不同 UI 元素可根据需要标记为不同的渲染方式,以在满足业务需求、保证使用体验的情况下尽量提高渲染性能。

ModelUI 渲染方式简介:

UIKit 渲染通过系统原生 UIKit 控件渲染卡片,使用 UIKit 渲染时 ModelUI 相当于提供了一个线程安全的 UIKit 接口,在子线程完成数据绑定、布局计算后 ModelUI 会在主线程完成渲染,使用 UIKit 渲染时只减少了部分主线程耗时,性能提升有限。

YYKit 渲染使用开源项目 YYKit 控件渲染 UI,YYKit 较 UIKit 性能有所提升,结合子线程数据绑定、布局计算,YYKit 渲染较 UIKit 渲染性能略有提升但整体不大。

Layer 渲染通过系统 QuartzCore 库中的 CALayer、CATextLayer 等渲染 UI,Layer 渲染不响应点击事件,较 UIKit 渲染、YYKit 渲染更为轻量,显著减少图层混合等 GPU 渲染负担,性能较 UIKit、YYKit 进一步提升,首页使用 Layer 渲染后卡顿明显减少,但还有滑动掉帧、抖动等,性能尚不理想。

异步渲染使用系统 CoreGraphics 中的 C 语言绘制命令,在子线程将各 UI Model 绘制为一张图片,最后由 GPU 直接渲染结果图片到屏幕上,不需要 GPU 渲染每个控件,渲染结束后 ModelUI 使用 LRU 策略缓存结果图片,减少重复渲染,UI 卡片可以指定缓存 Id,在绑定重复数据时可直接复用上次渲染结果,进一步减少渲染耗时,同时解决了刷新闪烁问题。异步渲染极大减少了 GPU 渲染负担,充分发挥了硬件性能,性能提升较大,但异步渲染不能响应点击事件且只适用于静态 UI 卡片。

挖掘低端机性能极限:优酷iPhone首页性能优化 6

3)布局渲染线程池

ModelUI 维护了一个线程池用以布局和渲染,减少新线程开辟耗时,不同卡片可在多个线程同时布局、渲染,进一步挖掘多核硬件性能。

经过任务拆分、渲染方式优化后,主线程拥塞基本解决, GPU 负担大幅减少,从而降低 CPU、GPU 占用峰值,减少滑动卡顿,提高用户体验。

挖掘低端机性能极限:优酷iPhone首页性能优化 7

优化后卡片复用时序

  1. 不足

1)ModelUI 采用子线程渲染,在快速滑动需要大量渲染时限于 CPU 性能部分卡片渲染需要等待,导致卡片延时显示,但相比于卡顿,延时较小可以接受;

2)ModelUI 异步渲染方式只能展示静态 UI,对于 Gif 等场景需要结合原生控件,而切换逻辑需要业务层处理,对业务层有少量侵入;

3)ModelUI 异步渲染方式页面刷新时会有闪烁问题,主要由于数据更新时 UI 没有同步更新,需要在数据更新时清除上次渲染结果,结合渲染复用可以解决此问题,需要业务层处理相关逻辑。

四、优化效果

首页卡片使用 ModelUI 渲染后体验有较大提升,滑动时已无明显卡顿或掉帧,帧率提升 18% 左右,reuse 方法主线程耗时降低一半左右,图层混合、离屏渲染、像素对齐等 GPU 耗时问题也基本解决,GPU 占用降低 36%左右,整体效果较好。

  1. GPU 渲染负担大幅减少

挖掘低端机性能极限:优酷iPhone首页性能优化 8

iPhone6 plus 首页接入 ModelUI 后图层混合、离屏渲染等问题大部分得到解决

  1. Instrument 测试帧率显著提升

通过 Instrument 可以看到,帧率提升 18%左右,平均 GPU 占用降低近一半,虽然最低帧数据还不够理想,但结合架构层、网络层、数据中心优化后整体效果比较满意。

挖掘低端机性能极限:优酷iPhone首页性能优化 9

iPhone6 plus 优酷首页接入 ModelUI 后从轮播图滑动到单 Feed 区帧率统计

  1. 性能测试平台测试整体效果较好

通过优酷自动化测试平台,测试 iPhone6 上综合架构优化版首页帧率从 55 帧提高到 58 帧,最低帧由 26 帧提升到 48 帧。由于测试帧率原理、设备性能不同测试数据有所差异,整体可以作为改善参考。

挖掘低端机性能极限:优酷iPhone首页性能优化 10

优酷自动化测试平台 iPhone6 上优酷首页优化前后帧率曲线对比

五、结语

性能是 APP 核心指标之一,而随着业务迭代的增加,UI 越来越复杂,难免要使用一些高耗时的 UI 效果,如文本 size 计算、圆角阴影渐变等,导致 APP 性能逐渐下降,而开发同学编码习惯也不同,难以形成有效的性能机制,而 ModelUI 提供了一种性能卡口,将耗时任务拆分到子线程,减少主线程拥塞,从而确保了 APP 的渲染性能,最终充分发挥现有硬件的性能,以提供最好的用户体验。

作者 | 阿里文娱高级无线开发工程师 氚雨