iOS性能(一) UI优化
2019-05-26 本文已影响0人
枫林风雨
帧率-FPS
UI的性能主要的体现就是帧率(Frames Per Second),当快速滚动页面时能够保持较高帧率说明UI性能良好。性能标准理论上60最佳,一般可接受的标准为50fps,而低于45时用户就可以感受到页面反应的顿挫了,即掉帧。
查看帧率可以通过Xcode自带的调试工具Instrument
-> Core Animation
来查看。也可以结合CADisplayLink类自定义组件在app页面中显示帧率。
界面顿卡的原因
CPU限制
- 对象的创建,释放,属性调整。这里尤其要提一下属性调整,CALayer可做动画的属性调整的时候是会创建隐式动画的,是比较损耗性能的。
- 视图和文本的布局计算,AutoLayout的布局计算都是在主线程上的,所以占用CPU时间也很多 。
- 文本渲染,诸如UILabel和UITextview都是在主线程渲染的
- 图片的解码,这里要提到的是,通常UIImage只有在交给GPU之前的一瞬间,CPU才会对其解码。
GPU限制
- 视图的混合。比如一个界面十几层的视图叠加到一起,GPU不得不计算每个像素点药显示的像素
- 离屏渲染
- 半透明,GPU不得不进行数学计算,如果是不透明的,CPU只需要取上层的就可以了
- 浮点数像素
优化
原则
UI优化最好是通过真机和所支持的最低配置来调试,因为:
- Mac上的CPU比ios设备要快很多
- Mac上的GPU和iOS设备上的不一样,模拟器不得已需要在软件层面(CPU)模拟iOS设备,所以GPU的相关操作在模拟器上面运行的会更慢
以上原因使得模拟器不能准确提供真机的性能参数。此外,调试时最好使用发布配置,而不是调试模式。因为当用发布环境打包的时候,编译器会引入一些提高性能的优化,比如:去除调试符号或者移除并重新组织代码。
调试工具
- 不越狱的情况下使用的工具一般就是Xcode自带的View Debug工具了,工具路径:
Xcode
->Debug
->View Debugging
->Rendering
。 - 如果有越狱手机则可以使用第三方的强大工具
Reveal
参考。
Rendering详解
Rendering调试归属于CoreAnimation核心动画调试的一部分。
Rendering的几种模式:
- Color Blended Layers
- Color Hits Green and Misses Red
- Color Copied Images
- Color Misaligned Images
- Color Offscreen-Rendered Yellow
- Color OpenGL Fast Path Blue
- Flash Updated Region
- Color Immediately
说明如下:
- 图层混合情况,没有混合的部分会是绿色,混合最严重的部分会是红色。大量的图层混合会消耗GPU的时间,因为对于一个像素点,GPU不能简单的使用最上层的视图的颜色,而是需要进行计算叠加(CPU计算生成Bitmap后提交给GPU进行混合)。造成图层混合主要原因有不透明度、渐变、阴影等。不透明度包括图片的alpha通道。
- 当使用shouldRasterize属性的时候,耗时的图层绘制会被缓存,然后当做一个简单的扁平图片呈现。当缓存无法使用必须重建的时候,会被高亮为红色。大量的缓存图层还会造成VM内存变大,所以如果图层很少会被重用时还是不要开启shouldRasterize。
- 如果图像的颜色格式不是GPU可以直接处理的格式,那么图像会被CPU先做格式转换。这个过程包括复制原图和转换计算,这两个过程对于都是CPU都是非常昂贵的操作,会导致性能损耗,比如电量增多,发热强变大等。这种情况的图片此时会显示为蓝色。
题外话:苹果的GPU只解析32bit的颜色格式,当然其它的计算机也是如此。计算机使用的32位颜色也就是常用的RGBA颜色,红,绿,蓝各占8个位,再增加8位透明度,就有了32位色。32位色其实就是24位真彩色。
- 图片有没有像素不对齐,有没有拉伸和缩放,如果有那么图片区域会高亮成黄色。
- 离屏渲染的部分会被高亮成黄色。
- 这个选项会对任何直接使用OpenGL绘制的图层进行高亮。
- 这个选项会对重绘的内容高亮成黄色(也就是任何在软件层面使用Core Graphics绘制的图层)。
- 通常Core Animation Instruments以每毫秒10次的频率更新图层调试颜色。对某些效果来说,这显然太慢了。这个选项就可以用来设置每帧都更新
优化方案
- 使用FaceBook的AsyncDisplayKit来写复杂的界面,能够获得异步绘制,预先加载等诸多好处。
- YYKit图文混排引擎,大多数性能要求较高的界面就是图文混排,比如微博Feed,微信朋友圈等界面。
-
异步绘制
,把复杂的界面,放到后台线程里绘制成一个bitmap,然后再显示。虽然有些延迟,不过换来的却是平滑的界面。 -
尽量使用CALayer
,因为Layer是一个轻量级的视图结构,它不接受通知,不接受触摸,不在响应链。所以,相对于UIView来说,它的性能较好。并且CALayer及其子类是可以使用GPU渲染的,能够硬件加速。 -
预加载与缓存
,对于复杂的TableView,可以对Cell视图的各个控件的大小,位置后台进行预计算,并且缓存起来。这样保证在heightForRow和cellForRow中不进行大量的计算。 -
图片的处理
,尽量使用成熟的库,比如SDWebImage等,能够在后台进行图片解码,减少CPU的使用。尽量不要变形图片,保证图片与view尺寸一致。