要理解卡顿原因,需要先了解16ms原则
https://www.cnblogs.com/upwgh/p/10897576.html
一.16ms原则
由于人眼的特殊构造,对于60fps以下的帧率画面,会给人一种卡顿的现象,所以就出现了16ms原则(1000ms/60fps = 16ms),即要保证页面16ms刷新一次。
Android系统每隔16ms发出vsync信号,触发对UI进行渲染,1s内大约刷新屏幕60次,显示60帧的数据。
fps:画面每秒钟传输的帧率,帧率越高,画面越流程,反之越卡顿
二.造成卡顿的原因
上面我们讲到了16ms原则,那么16ms原则对我们的UI产生了什么样的影响呢?
因为16ms原则,我们显示器将页面显示出来分两种情况:
1.上述步骤在16ms内完成,true→显示器直接显示。
2.上述步骤在16ms内没有完成(可能由于CPU计算的时间过长或者由于GPU的渲染时间过长,最终导致整个流程下来超过了16ms),false-->垂直同步等待下一帧完成。
解释一下垂直同步机制:比如说第一帧在16ms内渲染完成,并且显示出来了,第二帧在上述的处理流程中超过了16ms,在16ms内没有完成,那么,屏幕就不会显示第二帧的数据,依旧只显示第一帧的数据,接下来处理第三帧,第三帧的数据在16ms内处理完了上述的流程,那么结果就是屏幕会将第二帧的数据和第三帧的数据一起显示出来(如果在某一处出现了丢帧的情况,大概率会影响到后面的绘制也会出现丢帧的情况),如果计算器cpu的计算能力和gpu的渲染能力很差,就会出现我们说的UI卡顿的现象。(用LOL举一个例子,比如我们1-10帧都没有在16ms内完成(打团中,UI过于复杂),第11帧在16ms内完成(打完团,回家泡泉水),这时候就会把1-11帧的数据都显示出来,这时候给人的感觉就是花里胡哨的闪现出一堆技能)
看了上面的解释,是不是有一种明朗的感觉了,总的来说就是帧率过低,垂直同步机制的限制下,我们前面几帧的画面渲染不出来,直到某一帧我们的帧率正常了,这时候就会把前面的几帧一起渲染出来,这样就造成了我们所说的视觉上卡顿的现象了。
三,过度绘制造成的卡顿优化
2.过度绘制检测工具
开发者选项-->调试gpu过度绘制-->显示过度绘制区域
原色 – 没有被过度绘制 – 这部分的像素点只在屏幕上绘制了一次。
蓝色 – 1次过度绘制– 这部分的像素点只在屏幕上绘制了两次。
绿色 – 2次过度绘制 – 这部分的像素点只在屏幕上绘制了三次。
粉色 – 3次过度绘制 – 这部分的像素点只在屏幕上绘制了四次。
红色 – 4次过度绘制 – 这部分的像素点只在屏幕上绘制了五次。
我们的目标是尽量减少红色,看到更多的蓝色!!!
3.如何避免过度绘制
1)避免UI层级嵌套的过深
2)减少不必要的背景设置(根节点背景是否可以不要、系统主题背景是否可以不要等等)
3)使用merge标签减少布局嵌套层次
4)使用ConstraintLayout替代常见嵌套布局,减少布局层次
5)在自定义view的时候,使用Canvas的clipRect和clipPath方法限制View的绘制区域(覆盖区域不需要绘制)