iOS性能优化 - 工具Instruments之CoreAnimation

准备工做

在性能优化中一个最具参考价值的属性是FPS:全称Frames Per Second,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具备参考价值,FPS值的大小体现了页面的流畅程度高低,当低于45的时候卡顿会比较明显。缓存

  • 注意点:
  1. 使用真机调试。性能优化

  2. 最好使用release包测试(release是发布版本,苹果会在release包中作不少优化工做,所以用release包测试出来的性能才是最真实的)。 启动程序点击XCode选择左上角-XCode->Open Developer Tool ->Instruments,打开Instruments再选择CoreAnimation。iphone

打开CoreAnimation性能

图中1是FPS值。
图中2是不一样纬度的调试选项(下面会逐个介绍)。


Color Blended Layers (图层混合)

这个选项是检测哪里发生了图层混合,先介绍一下什么是图层混合?不少状况下,界面都是会出现多个UI控件叠加的状况,若是有透明或者半透明的控件,那么GPU会去计算这些这些layer最终的显示的颜色,也就是咱们肉眼所看到的效果。例如一个上层Veiw颜色是绿色RGB(0,255,0),下层又放了一个View颜色是红色RGB(0,0,255),透明度是50%,那么最终显示到咱们眼前的颜色是蓝色RGB(0,127.5,127.5)。这个计算过程会消耗必定的GPU资源损耗性能。若是咱们把上层的绿色View改成不透明, 那么GPU就不用耗费资源计算,直接显示绿色。测试

若是出现图层混合了,打开Color Blended Layers选项,那块区域会显示红色,因此咱们调试的目的就是将红色区域消减的越少越好。那么如何减小红色区域的出现呢?只要设置控件不透明便可。优化

  1. 设置opaque 属性为true。
  2. 给View设置一个不透明的颜色,没有特殊须要设置白色便可。

若是你在lldb中po打印某个控件,你会发现打印出来的数据中,控件的opaque都是true,由于控件这个属性的默认值都是true,因此第一种方法能够直接忽略掉。使用第二种方法你会发现以前红色的都消除掉了。动画

设置不透明以前: 3d

设置不透明以后: 调试

label.backgroundColor = [UIColor whiteColor];
label.layer.masksToBounds = YES;code

到这里你可能奇怪,设置label的背景色第一行不就够了么,为何还有第二行?这是由于若是label的内容是中文,label实际渲染区域要大于label的size,最外层多了一个sublayer,若是不设置第二行label的边缘外层灰出现图层混合的红色,所以须要在label内容是中文的状况下加第二句。单独使用label.layer.masksToBounds = YES是不会发生离屏渲染。

注意点:UIImageView控件比较特殊,不只须要自身这个容器是不透明的,而且imageView包含的内容图片也必须是不透明的,若是你本身的图片出现了图层混合红色,先检查是否是本身的代码有问题,若是确认代码没问题,就是图片自身的问题


Color Hits Green and Misses Red(光栅化)

这个选项主要是检测咱们是是否正确使用layer的shouldRasterize属性,shouldRasterize = YES开启光栅化。什么是光栅化?光栅化是将一个layer预先渲染成位图(bitmap),再加入到缓存中,成功被缓存的layer会标注为绿色,没有成功缓存的会标注为红色,正确使用光栅化能够获得必定程度的性能提高。

适用状况:通常在图像内容不变的状况下才使用光栅化,例如设置阴影耗费资源比较多的静态内容,若是使用光栅化对性能的提高有必定帮助。
非适用状况:若是内容会常常变更,这个时候不要开启,不然会形成性能的浪费。 例如咱们在使用tableViewCell中,通常不要用光栅化,由于tableViewCell的绘制很是频繁,内容在不断的变化,若是使用了光栅化,会形成大量的离屏渲染下降性能。

若是你在一个界面中使用了光栅化,刚进去这个页面的全部使用了光栅化的控件layer都会是红色,由于尚未缓存成功,若是上下滑动你会发现,layer变成了绿色。可是若是你滑动幅度较大会发现,新出现的控件会是红色而后变成绿色,由于刚开始这些控件的layer尚未缓存。

注意点:

  1. 系统给光栅化缓存分配了一个固定的大小,所以不能过分使用,若是超出了缓存也会形成离屏渲染。
  2. 缓存的时间为100ms,所以若是在100ms内没有使用缓存的对象,则会从缓存中清除。


Color Copied Images(图片颜色格式)

Shows images that are copied by Core Animation in blue苹果官方注释被拷贝给CPU进行转化的图片显示为绿色。那么这句话怎么理解呢?若是GPU不支持当前图片的颜色格式,那么就会将图片交给CPU预先进行格式转化,而且这张图片标记为蓝色。那么GPU支持什么格式呢?苹果的GPU只解析32bit的颜色格式,若是使用Color Copied Images去调试发现是蓝色。

知识扩展:32bit指的是图片颜色深度,用“位”来表示,用来表示显示颜色数量,例如一个图片支持256种颜色,那么就须要256个不一样的值来表示不一样的颜色,也就是从0到255,二进制表示就是从00000000到11111111,一共须要8位二进制数,因此颜色深度是8。一般32bit色彩中使用三个8bit分别表示R红G绿B蓝,还有一个8bit经常使用来表示透明度(Alpha)。


Color Immediately(颜色刷新频率)

当执行颜色刷新的时候移除10ms的延迟,由于可能在特定状况下你不须要这些延迟,因此使用此选项加快颜色刷新的频率。不过通常这个调试选项咱们是用不到的。


Color Misaligned Images(图片大小)

这个选项能够帮助咱们查看图片大小是否正确显示。若是image size和imageView size不匹配,image会出现黄色。要尽量的减小黄色的出现,由于image size与imageView size不匹配,会消耗资源压缩图片。下图中的image实际size(81,110),顶部image正常,底部image出现黄色由于放在了一个size x 2的imageView容器中。


Color Offscreen-Rendered Yellow(离屏渲染)

离屏渲染Off-Screen Rendering 指的是GPU在当前屏幕缓冲区之外新开辟一个缓冲区进行渲染操做。还有另一种屏幕渲染方式-当前屏幕渲染On-Screen Rendering ,指的是GPU的渲染操做是在当前用于显示的屏幕缓冲区中进行。 离屏渲染会先在屏幕外建立新缓冲区,离屏渲染结束后,再从离屏切到当前屏幕, 把离屏的渲染结果显示到当前屏幕上,这个上下文切换的过程是很是消耗性能的,实际开发中尽量避免离屏渲染。

触发离屏渲染Offscreen rendering的行为:

  1. drawRect:方法
  2. layer.shadow
  3. layer.allowsGroupOpacity or layer.allowsEdgeAntialiasing
  4. layer.shouldRasterize
  5. layer.mask
  6. layer.masksToBounds && layer.cornerRadius

这里有须要注意的是第三条layer.shouldRasterize ,其实就是咱们本文讲的第三个选项光栅化,光栅化会触发离屏渲染,所以光栅化慎用。

第六条设置圆角会触发离屏渲染,若是在某个页面大量使用了圆角,会很是消耗性能形成FPS急剧降低,设置圆角触发离屏渲染要同时知足下面两个条件:
layer.masksToBounds = YES;
layer.cornerRadius = 5;

下图是给一个label设置了圆角,触发离屏渲染:

为了尽量避免触发离屏渲染,咱们能够换其余手段来实现必要的功能:

  1. 阴影绘制shadow:使用ShadowPath来替代shadowOffset等属性的设置
    imageViewLayer.shadowPath = CGPathCreateWithRect(imageRect, NULL);
  2. 利用GraphicsContex生成一张带圆角的图片或者view,这里不写具体实现过程,须要的能够度娘Copy,不少现成的代码。

Color Compositing Fast-Path Blue (快速路径)

Places a blue overlay over content that is detached from the compositor.标记由硬件绘制的路径为蓝色,蓝色越多越好,能够对直接使用OpenGL绘制的图层进行高亮。没有对OpenGL有过多的研究,因此这里没办法给出demo,你们只须要记住蓝色越多越好就ok。


Flash Updated Regions (重绘区域)

Colors regions on your iOS device in yellow when those regions are updated by the graphics processor.这个选项会对重绘的内容高亮成黄色,重绘就是指使用Core Graphics绘制,绘制会损耗必定的性能,所以重绘区域应该越小越好。下图是用真机进入原生地图开启Flash Updated Regions 调试的效果图,很惋惜截屏不能截到黄色的区域,所以我用红框圈起来,一共两处,坐上角的是在不停的刷新页面,右下角是在不停的刷新当前位置,所以都是使用Core Graphics重绘刷新的一种场景,而且你能够发现黄色区域很小,区域越小性能越好。

相关文章
相关标签/搜索