UIKit 性能优化(图层混合、光栅化、颜色格式、图片大小、离屏渲染)

UIKit 性能优化(图层混合、光栅化、颜色格式、图片大小、离屏渲染)


图层混合

透明度设置为100%

如果某一块区域上覆盖了多个layer,最后的显示效果受到这些layer的共同影响。举个例子,上层是蓝色(RGB=0,0,1),透明度为50%,下层是红色(RGB=1,0,0)。那么最终的显示效果是紫色(RGB=0.5,0,0.5)。这种颜色的混合(blending)需要消耗一定的GPU资源,因为实际上可能不止只有两层。如果只想显示最上层的蓝色,可以把它的透明度设置为100%,这样GPU会忽略下面所有的layer,从而节约了很多不必要的运算。

UIImageView的图片也不能含有alpha通道

图像自身的性质可能会对结果有影响

设置 backgroundColor 属性(如果不设置背景颜色,控件依然会被认为是透明的)

虽然在白色背景下,无法肉眼看到效果,但重新调试后我们可以发现label的红色消失了。也正是因为对背景颜色的不重视,它成了影响滑动性能的第一个杀手。

如果label文字有中文,依然会出现图层混合,这是因为此时label多了一个sublayer

怎么解决。。

光栅化

光栅化是将一个layer预先渲染成位图(bitmap),然后加入缓存中。如果对于阴影效果这样比较消耗资源的静态内容进行缓存,可以得到一定幅度的性能提升

label.layer.shouldRasterize = true

因为layer进行光栅化后渲染成位图放在缓存中。

缓存中的对象有效期只有100ms,即如果在0.1s内没有被使用就会自动从缓存中清理出去。

光栅化的缓存机制是一把双刃剑,先写入缓存再读取有可能消耗较多的时间。因此光栅化仅适用于较复杂的、静态的效果。

光栅化会导致离屏渲染

颜色格式

像素在内存中的布局和它在磁盘中的存储方式并不相同。

当我们打开JPEG格式的图片时,CPU会进行一系列运算,将JPEG图片解压成像素数据。显然这个工作会消耗不少时间,所以不应该在滑动时进行,我们应该预先处理好图片。

Commit Transaction和Decode在同一帧内进行,如果这两个操作的耗时超过16.67s,Draw Calls就会延迟到下一帧,从而导致fps值的降低。下面是Commit Transaction的详细流程:

在第三步的Prepare中,CPU主要处理两件事:

把图片从PNG或JPEG等格式中解压出来,得到像素数据
如果GPU不支持这种颜色各式,CPU需要进行格式转换

使用instrument 的core animation 的 Color Copied Images检测图片格式

确保图片颜色格式能被GPU支持

图片大小

图片如果需要缩放会占用一定时间,确保图片大小与frame一致,不要在滑动的时候缩放图片

离屏渲染

离屏渲染会比普通渲染占用更多时间,以下几个会导致离屏渲染

  • 重写drawRect方法

    • 会导致大量内存消耗
  • 有mask(layer.maskToBounds)或者是阴影(layer.shadow),模糊效果也是一种mask

      //阴影效果可以指定阴影路径,否则core animation会去自动计算,就会触发离屏渲染
      imgView.layer.shadowPath = UIBezierPath(rect: imgView.bounds).CGPath 
    
  • layer.shouldRasterize = true


原文地址:UIKit性能调优实战讲解

参考链接:内存恶鬼drawRect

posted @ 2016-03-18 15:18  孙焱焱  阅读(621)  评论(0编辑  收藏  举报