提升动画性能
提升动画性能
对于基于应用程序的动画来说,
CoreAnimation
是提高帧率的好方法,但是它的使用并不能保证性能的提高。尤其在 OS X中,还要选择使用CoreAnimation
的最有效方式。所有性能相关的问题,可以使用Instruments
来衡量和跟踪应用在一段时间内的性能,这才能确保性能的提升而不是降低。
为 OS X 视图待批最佳的重画策略
NSView
类包括基于图层的视图的默认重画策略是原始的绘制行为。如果使用图层支持的视图,要检查重绘策略的选择,同时要为应用选择最佳性能的策略。在大多数情况下,默认的策略不是性能最好的。相反NSViewLayerContentsRedrawOnSetNeedsDisplay
策略更可能减少应用绘制的工作量而提高性能。其它的策略可能也会指定视图提供更好的性能
The Layer Redraw Policy for OS X Views Affects Performance
OS X 中更新图层来优化渲染路径
OS X 10.8 及以上视图有两种方式去更新底层图层内容。在10.8以前,图层从视图的
drawRect:
方法捕获绘制命令到底层位图图像中。缓坡绘制命令是有效的做法,但不是在所有情况下都是最有效的。如果知道直接提供图层的内容而不需要实际渲染,可以使用updateLayer
方法
Using a Delegate to Provide the Layer's Content 更多关于不同渲染路径信息
一般提示和技巧
有几种方式使图层实现更高效。但是与很多优化一样,需要测量当前代码性能再尝试优化。为你提供一个基准,判断优化是否有效。
-
尽量使用不透明的图层
设置opaque
为 YES,这样就不用去维护图层的 alpha通道。这意味着合成时不用将内容和图层的背景混合在 一起从而节约渲染时间。此属性主要用于作为图层支持视图的一部分,或CoreAnimation
动画创建底层位图的情况下。 如果直接给图层contents
属性赋值一张图片,不管opaque
属性值多少,图片的 alpha 通道都会保留。 -
为
CAShapeLayer
对象使用简单路径
CAShapeLayer
通过提供的渲染路径创建内容在合成时给位图图像。这样做的好处是图层总是以尽可能高的分辨率绘制路径,但这要花费更多渲染时间为代价。 如果提供的路径复杂,路径的栅格化可能更大的代价。如果图层尺寸经常变化(导致经常重绘)大量时间会用在绘那将成为性能瓶颈。 一种最小化图形绘制时间方式是将复杂的图形拆分成简单的图形。使用简单的路径和多个CAShapeLayer
对象层叠起来合成程序时将比绘制一个超大复杂的路径要更快。 因为绘制的操作在 CPU,而合成的操作在 GPU。 -
为相同图层显示设置内容
如果为多个图层使用同一张图片,加载图片并赋值到这些图层的contents
属性上。这样会阻止图层分配存储空间,从而图层使用图片自己的存储空间。 这样当多个图层使用相同图片时,图层使用的相同内容而不需要为他们自己拷贝一份。 -
尽量为图层尺寸设置为整数
为了得到最好的结果,图层对象的宽和高总是设置为整数值。尽管指定图层边界为浮点数值,但图层边界最终用于创建位图图像。 为宽高指定整数值简化CoreAnimation
创建和管理后备存储和图层其它信息的工作 -
根据需要使用异步图层渲染
在代理的drawLayer:inContext:
或者视图drawRect:
方法中的任何绘制通常是同步发生在应用的主线程。在一些情况下,同步绘制内容可能不会提供最佳性能。 如果注意到你的动画执行的不是很好,可以尝试启用图层上的drawsAsynchronously
属性把这些操作移动到后台线程。 但这样做要确保你的绘制代码是线程安全。与往常一样将代码放入生产环境前,要衡量下异步绘制的性能。 -
图层添加阴影时,指定一个阴影路径
让CoreAnimation
决定阴影形状是昂贵的且影响应用性能。与其这样,不如使用shadowPath
指定显示指定阴间形状。 当为此属性指定一个路径对象,CoreAnimation
使用保存的图形绘制和缓存阴影效果。如果图层图形从不改变或几乎不改变,这会大大的提高性能而减少大量的渲染。