iOS卡顿优化
2020-07-06 本文已影响0人
Vanha
一、成像原理
成像是CPU、GPU、显示器是协同完成的。CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,然后显示在屏幕上。
image.png二、卡顿产生原因
在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到帧缓冲区去,等待下一次 VSync 信号到来时显示到屏幕上。由于垂直同步的机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。
image.png从上面的图中可以看到,CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。
三、检测
1、平时所说的“卡顿”主要是因为在主线程执行了比较耗时的操作
2、可以添加Observer到主线程RunLoop中,通过监听RunLoop状态切换的耗时,以达到监控卡顿的目的
四、优化
- CPU 优化
1、尽量提前计算好布局,在有需要时一次性调整对应的属性,不要多次修改属性
2、Autolayout会比直接设置frame消耗更多的CPU资源
3、图片的size最好刚好跟UIImageView的size保持一致
4、控制一下线程的最大并发数量
5、尽量把耗时的操作放到子线程
6、文本处理(尺寸计算、绘制)
7、图片处理(解码、绘制) - GPU 优化
1、尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示
2、GPU能处理的最大纹理尺寸是4096x4096,一旦超过这个尺寸,就会占用CPU资源进行处理,所以纹理尽量不要超过这个尺寸
3、尽量减少视图数量和层次
4、减少透明的视图(alpha<1),不透明的就设置opaque为YES
5、尽量避免出现离屏渲染 - 离屏渲染(以下操作会触发离屏渲染)
1、光栅化 ,layer.shouldRasterize = YES
2、遮罩,layer.mask
3、圆角,同时设置layer.masksToBounds = YES、layer.cornerRadius大于0。考虑通过CoreGraphics绘制裁剪圆角,或者叫美工提供圆角图片
4、阴影,layer.shadowXXX 。如果设置了layer.shadowPath就不会产生离屏渲染