概述
iOS界面优化 ——卡顿检测和优化方案
- 1. 卡顿原理
- 2. 卡顿检测
- 3. 界面优化
1. 卡顿原理
卡顿,也就是掉帧。当UIView
被绘制时,cpu
执行drawrect
,通过context
将数据写入backingstore
。
当backingstore 写完后,通过 render server
交给gpu
去渲染,渲染的东西放到framebuffer里面,然后通过Video Controller交给monitor进行显示。说到底cpu
就是做绘制
的操作把内容放到缓存里,gpu
负责从缓存里读取数据然后渲染
到屏幕上。
最开始时,FrameBuffer
只有一个,这种情况下FrameBuffer的读取和刷新有很大的效率问题,如果gpu卡在那边,那么FrameBuffer接受不到消息,就会闲置。为了解决这个问题,引入了双缓存区
。即双缓冲机制。在这种情况下,GPU会预先渲染好一帧放入FrameBuffer,让视频控制器读取,当下一帧渲染好后,GPU会直接将视频控制器的指针指向第二个FrameBuffer。这时候,如果中间有的帧在一定时间内没有渲染完,那么就会被丢弃掉,转而去渲染下一个帧。这时候,就会出现卡顿。
这里采用了垂直同步信号机制来进行帧和帧的切换。当开启垂直同步后,GPU会等待显示器的VSync信号发出后,才进行新的一帧渲染和FrameBuffer更新。而目前iOS设备中采用的正是双缓存区+VSync
2. 卡顿检测
这里推荐三种卡顿监控的方案:
-
FPS监控
:为了保持流程的UI交互,App的刷新应该保持在60fps左右,其原因是因为iOS设备默认的刷新频率是60次/秒,而1次刷新(即VSync信号发出)的间隔是 1000ms/60 = 16.67ms,所以如果在16.67ms内没有准备好下一帧数据,就会产生卡顿。主要通过CADIsplayLink实现。参照YYKit中的YYFPSLabel,借助link的时间差,来计算一次刷新刷新所需的时间,然后通过 刷新次数 / 时间差 得到刷新频次,并判断是否其范围,通过显示不同的文字颜色来表示卡顿严重程度。 -
主线程卡顿监控
:通过子线程监测主线程的RunLoop,判断两个状态(kCFRunLoopBeforeSources 和 kCFRunLoopAfterWaiting)之间的耗时是否达到一定阈值 -
第三方工具:OC:微信卡顿检测工具
matrix
,滴滴卡顿方案DoraemonKit
,Swift:ANREye
通过注释可以得到CADisplayLink是一个时间长度为vsync的timer。
3. 界面优化
-
预排版
:尽量提前计算视图布局,例如提前算出cell的行高,缓存cell的行高来避免多次计算。 -
预解码
&预渲染
:
图片加载流程:
图片要显示,就要加载一个UIImage,UIImage
是一个模型
,里面包含Data Buffer
和imageBuffer
,然后由Controller控制UIImage显示在UIImageView上面的。
其中Data Buffer
进行解码然后缓存到imageBuffer
里面,然后才可以由Frame Buffer
进行渲染。
在SDWebImage里面就有预解码的步骤:
-
按需加载
,例如在TableView中滑动时不加载图片,使用默认占位图,而是在滑动停止时加载 -
异步渲染
- UIView 和 CALayer都是 UI 操作的对象
- UIView是 CALayer用于交互的对象,UIView是CALayer的delegate ,UIView是UIResponder的子类,其中提供了很多CALayer所没有的交互接口,主要负责处理用户触发的各种操作,给CALayer 提供内容,
- CALayer主要负责绘制,在图像和动画上渲染性能更好;
异步渲染的原理其实也就是在子线程将所有的视图绘制成一张位图,然后回到主线程赋值给 layer的 contents,Graver框架的异步渲染流程如下:
最后会得到一张图,这样也减少了图层的层级。
- 尽量
避免使用透明view
,因为使用透明view,会导致在GPU中计算像素时,会将透明view下层图层的像素也计算进来,即颜色混合处理, 少使用addView
给cell动态添加view尽量用轻量级
的对象代替重量级的对象,可以对性能有所优化,例如 不需要相应触摸事件的控件,用CALayer代替UIView- 尽量减少对UIView和CALayer的属性修改
- CALayer内部并没有属性,当调用属性方法时,其内部是通过运行时resolveInstanceMethod为对象临时添加一个方法,并将对应属性值保存在内部的一个Dictionary中,同时还会通知delegate、创建动画等,非常耗时
- UIView相关的显示属性,例如frame、bounds、transform等,实际上都是从CALayer映射来的,对其进行调整时,消耗的资源比一般属性要大
- 当有大量对象释放时,也是非常耗时的,尽量挪到后台线程去释放
减少图层的层级
减少离屏渲染
最后
以上就是彩色大象为你收集整理的iOS界面优化 ——卡顿检测和优化方案的全部内容,希望文章能够帮你解决iOS界面优化 ——卡顿检测和优化方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复