离屏渲染意味着某一区域每帧渲染了两次。大部分离屏幕渲染由阴影和遮障绘制造成。以阴影绘制为例例,iOS 会先绘制目标的阴影,然后绘制目标本身。当我们没有设置阴影的路径时,iOS 在每次绘制前会递归每个子层来计算阴影的精确路径,这是非常消耗性能的,也导致了动画时出现卡顿。
因此,一般情况下需要指定阴影的路径。当 View 的 bound 改变时,重新设置阴影路径。如果 View 的 bound 做动画,则需要使用 CAAnimation 为 shadowPath 设置动画。
Blending
iOS 在渲染每一帧时,都将计算每一个像素点的颜色。当最上面的层不透明时,只需取最上面的层的颜色。而当上面的层存在透明度时,需要混合每一层的颜色来计算得到最终显示的颜色。自上而下有透明度的层越多,计算量越大,这也会导致动画时性能降低。因此,我们在开发中,要尽量减少不必要的透明层。
使用 Instruments 检测绘图性能
使用 Instruments 的 Core Animation 模板可以很方便的检测应用中的 Blending 和 Offscreen-Rendered 。
勾选 Color Offscreen-Rendered Yellow 选项将高亮进行离屏渲染的区域。
勾选 Color Blended Layers 将显示进行图层混合的区域,颜色越深表示计算量越大。
iOS 提升 UIImage 性能
使用 UIImage 加载大图片时,有时会导致界面卡顿,特别是在 UITableView 中上下拖动切换不同图片时更为明显。这是因为 UIImage 初始化后仅仅是把图片加载到内存中,而实际的解码和重采样是在图片需要显示时才进行(例如在 UIImageView 中),此时这些操作都在 UI 主线程中完成。因此,当图片比较大(尤其是图片大小和实际显示大小相差较大)时,解码和重采样是一个非常耗性能的操作,导致 UI 卡顿。解决方法是在子线程中先完成重采样,这样在显示时就省去了重采样所需的性能消耗。
图片重采样(参考官方例子 LazyTableImages ):