iOS性能优化系列篇之“列表流畅度优化”

卡顿产生的原因

在总体原则篇中提到,五大原则中的其中一个就是要理解优化任务的底层运行机制,因为只有深入了解底层机制才能更好的有针对性的提出更优的解决方案,所以在进行列表流畅度优化前,我们一定要弄清楚一个view从创建到显示到屏幕上都经历了那些过程,在这些过程中那些方面可能会导致性能瓶颈,以及造成卡顿的底层原因是什么。

我们知道iOS设备大部分情况下,屏幕刷新频率是60hz(ProMotion下是120hz),也就是每隔16.67ms会进行一次屏幕刷新。每次刷新时,需要CPU和GPU配合完成一次图像显示。其主要流程如下:

应用内:

布局。CPU创建view,设置其属性(frame、background color等等)
创建backing images。setContents将一个image传給layer或者通过 drawRect:或 drawLayer:inContext绘制
准备。Core Animation将layer发送到render server前的一些准备工作,比如图片解码等。
提交。Core animation将layers打包通过 IPC (Inter-Process Communication) 发送到render server
应用外(render server):

设置用来渲染的OpenGL triangles(如果是有动画,还需计算动画layer的属性的中间值)。
渲染这些可见的triangles,将结果提交到视频缓冲区
视频控制器以60hz频率读取缓冲区内容显示到显示器,如果在16.67ms内没有完成提交,则会被丢弃。
在这里插入图片描述
从上面的图中可以看到,在view显示的过程中,CPU和GPU都各自承担了不同的任务,CPU和GPU不论哪个阻碍了显示流程,都会造成掉帧现象。所以优化方法也需要分别对CPU和GPU压力进行评估和优化,在CPU和GPU压力之间找到性能最优的平衡点, 无论过度优化哪一方导致另一方压力过大都会造成整体FPS性能的下降。而寻找平衡点的过程则因项目特点不同而不同,并没有一套通用的方法,需要我们用instrument等性能评测工具,根据实际app的性能度量结果去做优化,不能凭空乱猜。

CPU优化
我们先看table view在滑动过程中CPU占用的情况。
在这里插入图片描述
从上图可以看出,在滑动过程中CPU占用特点是:

滑动时CPU占用率高、空闲时CPU占用率底
主线程CPU占用高、子线程CPU占底
根据上述特点我们可以做如下优化:

预加载,空间换时间

为什么要预加载:

滑动时CPU占用过高,16.67ms内无法完成内容提交—>导致卡顿
滑动时CPU占用率高,但空闲时CPU占用率底—>CPU占用分布特点
利用CPU空闲时间预加载,降低滑动时CPU占用峰值—>解决卡顿
通过预加载我们希望达到的CPU理想占用效果如下:
在这里插入图片描述
预加载内容:

静态资源预加载

如何预加载:创建列表前找时机加载。如启动时、viewDidLoad、runloop空闲时等等
加载内容:缓存在磁盘的网络数据、图片、其他滑动时需要的耗时的资源
注意事项:在预加载带来的滑动性能提升和内存占用增加之间权衡
动态资源预加载

如何预加载:

在iOS10以后,UITableView和UICollectionView提供了预加载机制,iOS12开始prefeatching做了优化,不再与cell的加载同时并发进行,而是cell加载完成之后串行开始prefeatch,从而优化了流畅度

iOS10以前,也可以自己实现类似机制,主要利用的机制有:

UIScrollViewDelegate 提供滑动开始、结束、速度时机回调
indexPathsForRowsInRect 和layoutAttributesForElementsInRect 提供预加载的indexPath
可根据滑动速

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值