iOS.Core.Animation笔记三.Performance
19 May 2014第三部分,主要讲动画的性能
12. Tuning for speed
通常说CPU执行的是软件加速,GPU执行的是硬件加速。大多数的性能优化就是在这两者之间做选择,以避免任意一方过度消耗。
在iOS5及之前,我们知道有一个进程叫做SpringBoard,他其实是用来实现动画以及合成layer的独立进程。到iOS6及以后,负责这个任务的进程叫做BackBoard。我们一般也叫他Render Server。
animation通常的4个步骤
- Layout
- Display
- Prepare
- Commit
animation被提交到render server以后,还有2个步骤
- 计算所有layer的属性值并且建立OpenGL geometry进行渲染
- 渲染纹理到屏幕上
所以总共有6个步骤,前面5个由CPU实现,最后1个才有GPU实现。但是我们仍然可以在前面2个可以由我们控制的步骤中,抉择好哪些是CPU做前期,并传递给GPU继续完成。
GPU
可能会导致GPU慢的因素
- Too much geometry 太多的层次 虽然现在iOS的GPU可以绘制百万级别的三角形,但是准备过程中通过IPC传递到render server的数据,由于太多的layer会引起CPU的瓶颈。
- Too much overdraw 透支太多 透支主要是由重叠的半透明层引起的。
- Offscreen drawing 离屏绘制 离屏绘制的创建额外内存空间以及切换context都会引起GPU的额外消耗。使用某些特地的layer效果也会强制系统开启离屏预渲染,比如圆角,遮罩,阴影,rasterization。
- Too large images 太大尺寸的图片
CPU
可能会导致CPU慢的因素
- Layout calculations 复杂的layer层次结构,特别是iOS6以后提供的autolayout
- Lazy view loading 为了节约内存并减少系统启动时间,iOS只在view controller第一次展示在屏幕上的时候才被加载。如果展现在屏幕前需要太多的IO work就会导致不好的响应。
- Core Graphics drawing 如果实现了-drawRect:方法,或者是CALayerDelegate的-drawLayer:inContext:方法,你都创造了一个额外的性能开销。因为系统会自动创建一个同当前view size大小的image作为背景。
- Image decompression 虽然PNG和JPEG会比未压缩的bitmap小很多,但是当他被绘制到屏幕上前,仍然需要解压成完整的bitmap大小,通常是图片高x宽x4的bytes。
即使在layer被打包好并传递到了render server以后,cpu仍然需要计算每个可见的layer并转换成纹理三角形以供Open GL使用,因为GPU对Core Animation的结构式一无所知。
13. Efficient Drawing
使用正确的layer做正确的事,不仅速度比Core Graphic快很多,而且避免创建背景图像。
- CAShapeLayer 多边形、线条、曲线
- CATextLayer 文字
- CAGradientLayer 渐变效果
Dirty Rectangles
重绘部分区域
// 指定需要重绘的矩形区域
- (void)setNeedsDisplayInRect:(CGRect)invalidRect
// 并且在绘制的方法中进行判断是否在重绘的范围内
- drawRect:(CGRect)rect