1.首先新建项目-打开protect-profile
左侧 数值代表的fpsfps:我们知道任何屏幕总是有一个刷新率,比如iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,因此两次刷新之间的间隔为16.67ms。这段时间内屏幕内容保持不变,称为一帧(frame),fps表示frames per second,也就是每秒钟显示多少帧画面。对于静止不变的内容,我们不需要考虑它的刷新率,但在执行动画或滑动时,fps的值直接反映出滑动的流畅程度。
fps 为0时,表示屏幕未动! 一般fps<30 就有明显的卡顿 ,苹果官方给的标准值为fps为60!
一般影响fps的因素(掉帧):1.阻塞主线程,这就是官方为啥认定刷新UI必须在主线程的原因
2.原因较多,但是大部分原因是在于离屏渲染,渲染耗损过高.
顶部的震动条就是动态图!
右侧:color blended layers 颜色混合层
color hits green and missed red绿色和红色的颜色
flash update regionsFlash更新区
1、Color Blended Layers
(1)、图层混合
首先我们要明白像素的概念,屏幕上每一个点都是一个像素,像素有R、G、B三种颜色构成(有时候还带有alpha值)。如果某一块区域上覆盖了多个layer,最后的显示效果受到这些layer的共同影响。举个例子,上层是蓝色(RGB=0,0,1),透明度为50%,下层是红色(RGB=1,0,0)。那么最终的显示效果是紫色(RGB=0.5,0,0.5)。这种颜色的混合(blending)需要消耗一定的GPU资源,因为实际上可能不止只有两层。如果只想显示最上层的蓝色,可以把它的透明度设置为100%,这样GPU会忽略下面所有的layer,从而节约了很多不必要的运算。
(2)、调试Color Blended Layers
第一个调试选项”Color Blended Layers”正是用于检测哪里发生了图层混合,并用红色标记出来。因此我们需要尽可能减少看到的红色区域。一旦发现应该想法设法消除它。开始调试后勾选这个选项,我们在手机上可以看到如下的场景:
2、Color Hits Green and Misses Red
(1)、光栅化
光栅化是将一个layer预先渲染成位图(bitmap),然后加入缓存中。如果对于阴影效果这样比较消耗资源的静态内容进行缓存,可以得到一定幅度的性能提升。demo中的这一行代码表示将label的layer光栅化:
label.layer.shouldRasterize = YES;
(2)、调试Color Hits Green and Misses Red
它表示如果命中缓存则显示为绿色,否则显示为红色,显然绿色越多越好,红色越少越好。
注意:光栅化的核心在于缓存的思想。我们自己动手把玩一下,可以发现以下几个有意思的现象:
上下微小幅度滑动时,一直是绿色上下较大幅度滑动,新出现的label一开始是红色,随后变成绿色如果静止一秒钟,刚开始滑动时会变红。
这是因为layer进行光栅化后渲染成位图放在缓存中。当屏幕出现滑动时,我们直接从缓存中读取而不必渲染,所以会看到绿色。当新的label出现时,缓存中没有个这个label的位图,所以会变成红色。第三点比较关键,缓存中的对象有效期只有100ms,即如果在0.1s内没有被使用就会自动从缓存中清理出去。这就是为什么停留一会儿再滑动就会看到红色。
光栅化的缓存机制是一把双刃剑,先写入缓存再读取有可能消耗较多的时间。因此光栅化仅适用于较复杂的、静态的效果。通过Instrument的调试发现,这里使用光栅化经常出现未命中缓存的情况,如果没有特殊需要则可以关闭光栅化,所以我们做的第二个优化是注释掉下面这行代码
// label.layer.shouldRasterize = true
3、Color Copied Images
(1)、颜色格式
像素在内存中的布局和它在磁盘中的存储方式并不相同。考虑一种简单的情况:每个像素有R、G、B和alpha四个值,每个值占用1字节,因此每个像素占用4字节的内存空间。一张1920*1080的照片(iPhone6 Plus的分辨率)一共有2,073,600个像素,因此占用了超过8Mb的内存。但是一张同样分辨率的PNG格式或JPEG格式的图片一般情况下不会有这么大。这是因为JPEG将像素数据进行了一种非常复杂且可逆的转化。
CPU主要处理两件事:
(1)把图片从PNG或JPEG等格式中解压出来,得到像素数据
(2)如果GPU不支持这种颜色各式,CPU需要进行格式转换
(2)、调试Color Copied Images
第三个选项“Color Copied Images”就用来检测这种实时的格式转化,如果有则会将图片标记为蓝色。