列表的性能优化-图片性能

流畅的视觉:就是如丝般顺滑

不流畅视觉:”卡顿”,”抖动”,”迟顿感”

「帧率」Frames per Second(每秒帧数)这个指标 可以通过Instruments 工具中的 Core Animation来观察.(xCode -> Tools -> Instrument 或者commod + i 快捷键)

fps的值越大越好,当fps<=45就没明显的不流畅了,60以上肉眼察觉不到卡顿。

1: commod + i 打开instruments后,选择Core Animation选项。

2: 选择正确的设备(真机)和应用程序。

3: 点击instruments上红色开始按钮,然后滑动页面,在滑动屏幕时,帧率越高表示性能越好,帧率过低则意味着屏幕可能会出现卡顿。观察如图:

图片性能

在右下角面板的 Display Settings 区域,我们可以看到多个 Debug Options:

Color Blended Layers

这个选项选项基于渲染程度对屏幕中的混合区域进行绿到红的高亮显示,越红表示性能越差,会对帧率等指标造成较大的影响。红色通常是由于多个半透明图层叠加引起。

Color Hits Green and Misses Red

当 UIView.layer.shouldRasterize = YES时,耗时的图片绘制会被缓存,并当做一个简单的扁平图片来呈现。这时候,如果页面的其他区块(比如 UITableViewCell 的复用)使用缓存直接命中,就显示绿色,反之,如果不命中,这时就显示红色。红色越多,性能越差。因为栅格化生成缓存的过程是有开销的,如果缓存能被大量命中和有效使用,则总体上会降低开销,反之则意味着要频繁生成新的缓存,这会让性能问题雪上加霜,所以我们可以适当光栅化来优化图片性能,但是前提是这些图片变化不大,可以缓存的情况下。

Color Copied Images

对于 GPU 不支持的色彩格式的图片只能由 CPU 来处理,把这样的图片标为蓝色。蓝色越多,性能越差。因为,我们不希望在滚动视图的时候,由 CPU 来处理图片,这样可能会对主线程造成阻塞。

Color Immediately

通常 Core Animation Instruments 以每毫秒 10 次的频率更新图层调试颜色。对某些效果来说,这显然太慢了。这个选项就可以用来设置每帧都更新(可能会影响到渲染性能,而且会导致帧率测量不准,所以不要一直都设置它)。

Color Misaligned Images

这个选项检查了图片是否被缩放,以及像素是否对齐。被放缩的图片会被标记为黄色,像素不对齐则会标注为紫色。黄色、紫色越多,性能越差。

Color Offscreen-Rendered Yellow

在设置 .layer.masksToBounds = YES; 时会产生离屏渲染。这个选项会把那些离屏渲染的图层显示为黄色。黄色越多,性能越差。这些显示为黄色的图层很可能需要用 shadowPath 或者 shouldRasterize 来优化。

Color OpenGL Fast Path Blue

这个选项会把任何直接使用 OpenGL 绘制的图层显示为蓝色。蓝色越多,性能越好。如果仅仅使用 UIKit 或者 Core Animation 的 API,那么不会有任何效果。如果使用 GLKView 或者 CAEAGLLayer,那如果不显示蓝色块的话就意味着你正在强制 CPU 渲染额外的纹理,而不是绘制到屏幕。

Flash Updated Regions

这个选项会把重绘的内容显示为黄色。不该出现的黄色越多,性能越差。通常我们希望只是更新的部分被标记完黄色。


影响列表性能的图片处理方式:

1: 缩略图 和 原图。

2: 滚动页面多view情况下,圆角的处理。

一般情况下我们会这样做: .layer.masksToBounds = YES; .layer.cornerRadius = 2; 

masksToBounds 会导致拖慢帧率的原因其实都是Off-Screen Rendering(离屏渲染).

离屏渲染:是指CPU在当前屏幕缓冲区以外再开辟一个新的缓冲区进行渲染操作.

离屏渲染是一个很好优化性能的方式,但是频繁发生离屏渲染(滚动屏幕 就会很频繁啊)是非常耗时的。如果是一个圆角几乎不会对帧率有太大影响,关键数量要是好多个.通过上面的定义可以看出”离屏渲染”关键不是渲染 而是 离屏.

离屏代价:主要是创建缓冲区和上下文切换的原因。创建新的缓冲区代价都不算大,付出最大代价的是上下文切换!

关于上下文切换: 上下文切换在哪都是一个相当耗费时间的操作,不论是 CPU渲染或是进程切换.其过程:

(1)我们要保证当前屏幕渲染环境

(2)切换到一个新的绘制环境—>申请绘制资源—>初始化环境—>开始绘制—>绘制结束—>销毁绘制环境

(3)回到主屏幕呈现 或者 再开辟一个新的离屏渲染重复(2)

(1)非要作死使用layer.cornerRadius,记得还要添加下面方法

.layer.shouldRasterize = YES;//这样大部分情况下可以马上挽救你的帧数在55帧每秒以上。shouldRasterize = YES会使视图渲染内容被缓存起来,下次绘制的时候可以直接显示缓存,当然要在视图内容不改变的情况下。(具体解释  layer的头文件,进入查看这个属性的英文说明  不觉明厉)

.layer.rasterizationScale = [UIScreen mainScreen].scale;//需要适当设置"抗锯齿"  否则在retina的设备上这些视图会出现锯齿状。(具体了解参看 layer 属性)

(2)如果可以用切图遮罩代替的话 会效率很高

(3)预先缓存住 圆角的图片(预处理圆角图片在后台处理,处理完毕后缓存起来,再在主线程显示),来避免了离屏渲染

http://www.cnblogs.com/ioriwellings/p/5011993.html

https://www.zhihu.com/question/20382396

你可能感兴趣的:(列表的性能优化-图片性能)