• 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

  • 相关阅读:
    jni基础
    Rank Scores
    LeetCode:Longest Substring Without Repeating Characters
    LeetCode: Two Sum
    vim配置
    设计模式眨一眨
    分布式时序数据库InfluxDB
    地图坐标转换
    根据两点间的经纬度计算距离
    解密经纬度数据(火星坐标)
  • 原文地址:https://www.cnblogs.com/sunyanyan/p/5292257.html
Copyright © 2020-2023  润新知