这篇文章将为大家详细讲解有关iOS如何实现图形性能优化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
引言
当一个产品渐渐成熟,我们便开始重视产品性能的优化。而这其中图形性能的优化在iOS客户端占比较重要的部分。
这里我们将介绍Core Animation的运行机制,首先我们不要被它的名字误导了,Core Animation不是只用来做动画的,iOS视图的显示都是通过它来完成的,所以我们想要优化图形性能必须了解Core Animation。
下面我们根据苹果WWDC视频讲解来认识Core Animation工作机制,据此分析具体卡顿的原因,如何避免这些问题造成的卡顿,并且结合实际情况说明从哪些方面优化可以事半功倍。
Core Animation 工作机制
如上图所示,Core Animation在App将图层数据提交到应用外进程Render Server,这是Core Animation的服务端,把数据解码成GPU可执行的指令交给GPU执行。
可以看出一个问题渲染服务并不是在App进程内进行的,也就是说渲染部分我们无法进行优化,我们可以优化的点只能在第一个提交事务的阶段。那么这个阶段Core Animation到底做了什么呢?下面我们一起来看看!
Commit Transaction
提交事务分为四个阶段:布局、显示、准备、提交。
布局阶段
当调用addSubview时layer被加入到layer tree中,layoutSubviews被调用,创建view。同时还会进行数据查找,例如app做了本地化,label要显示这些本地化字符串必须从本地化文件中查找到对应语言的布局,这就涉及了I/O操作。所以这里主要是CPU工作,而瓶颈也会是CPU。
显示阶段
在这个阶段如果你重写了drawRect方法,Core Graphics会进行绘制渲染工作。为视图绘制寄宿图即contents。但是drawRect里绘制的内容不会立即显示出来,而是先备换窜起来,等需要的时候被更新到屏幕上。如手动调用setNeedsDisplay或sizeThatFits被调用,也可以设置cententMode属性值为UIViewContentModeRedraw当每次bounds改变会自动调用setNeedsDisplay方法。这个阶段主要是CPU和内存的消耗,很多人喜欢用Core Graphics的方法来绘制图形,认为可以提高性能,后面我们会说明这个方法的弊端。
准备阶段
这里的工作主要是图片的解码,因为大部分都是编码后的图片,要读取原始数据必须经过编码过程。并且当我们使用了iOS不支持的图片格式,即不支持硬编码,就需要进行转化工作,也是比较耗时的。所以这里就是GPU消耗,如果进行软解码也要消耗CPU。
提交阶段
最后一个阶段负责打包图层数据并发送到我们上面说的渲染服务中。这个过程是一个递归操作,图层树越复杂越是需要消耗更多资源。像CALaler有很多隐式动画属性也会在这里提交,省去了多次动画属性进程间的交互,提高了性能。
优化
根据上面我们所提到4个阶段,我们看看哪些因素会影响到App的性能,并且如何优化可以提高我们App的性能。
混合
平时我们写代码的时候,往往会给不同的CALayer添加不同的颜色,不同的透明度,我们最后看到是所有这些层CALayer混合出的结果。
那么在iOS中是如何进行混合的?前面我们说明了每个像素都包含了R(红)、G(绿)、B(蓝)和R(透明度),GPU要计算每个像素混合来的RGB值。那么如何计算这些颜色的混合值呢?假设在正常混合模式下,并且是像素对齐的两个CALayer,混合计算公式如下:
R = S + D * ( 1 – Sa )
苹果的文档中有对每个参数的解释:
The blend mode constants introduced in OS X v10.5 represent the Porter-Duff blend modes. The symbols in the equations for these blend modes are:
* R is the premultiplied result
* S is the source color, and includes alpha
* D is the destination color, and includes alpha
* Ra, Sa, and Da are the alpha components of R, S, and D