浅谈iOS中的视图优化

作者: kuailejim | 来源:发表于2016-04-19 18:27 被阅读6319次

    引言:
    让我们来思考几个问题,你开发过的产品,它还有可以优化的地方吗?能增加它的帧率吗?能减少多余的CPU计算吗?是不是存在多余的GPU渲染?业务这点工作量对于越来越强大的设备面前显得微不足道,但作为一个细心的开发者,我觉得很有必要来谈谈iOS中的视图优化。

    本文从开发者最容易犯错的地方出发,结合例子,从以下几个角度阐述如何进行视图优化:

    • Color Blended Layers
    • Color Copied Images
    • Color Misaligned Images
    • Color Offscreen-Rendered

    这个4个选项,可以从模拟器的Debug选项中看到

    模拟器选项
    别急,我们一个个来看,首先是Color Blended Layers

    Color Blended Layers

    官方是这么描述它的:

    Shows blended view layers. Multiple view layers that are drawn on top of each other with blending enabled are highlighted in red. Reducing the amount of red in your app when this option is selected can dramatically improve your app’s performance. Blended view layers often cause slow table scrolling.

    简单来说,屏幕上的每个像素点的颜色是由当前像素点上的多层layer(如果存在)共同决定的,GPU会进行计算出混合颜色的RGB值,最终显示在屏幕上。而这需要让GPU计算,所以我们要尽量避免设置alpha,这样GPU会忽略下面所有的layer,节约计算量。

    下面让我们来看一下设置alpha的效果,上面的灰色小块是透明的。


    demo 检测后

    效果很明显,设置了透明的view会让GPU计算图层混合后的最终结果。

    我想再提一下opaque这个属性,网上普遍认为view.opaque = YES,GPU就不会进行图层混合计算了。而这个结论是错误的,其实view.opaque事实上并没什么卵用。
    如果你真的想达到这个效果,可以用layer.opaque,这个才是正确的做法

    Color Copied Images

    "If an image is in a color format that the GPU can not directly work with, it will be converted in the CPU."

    Session 419 WWDC 2014中详细介绍了这货,其实这个东西跟开发者并没什么关系,遇到这种情况,我们大可以摔锅给设计(当然你乱做优化导致图片颜色格式改变,那就没办法了)。

    简而言之,苹果的GPU只解析32bit的颜色格式,记住是32bit
    如果你放一张图片,而它的颜色格式却不是32bit,CPU会先进行颜色格式转换,再让GPU渲染。乖乖的CPU就默默做了这个多余的工作。

    所以给你两个选择:

    • 让设计湿都给你切32bit的图
    • 自己去跑个异步线程来转换颜色去吧,不要去堵塞本来就压力很大的主线程!

    你选哪个?当然是让设计湿切图啦,我才不愿意多写代码。
    而且于情于理,就算异步转换颜色,也会导致性能损耗,比如电量增多,发热强变大等等等等

    上demo:

    demo
    检测后

    两个一样的图,仅仅是采用了不同颜色格式,上面是32bit,下面是8bit,于是乎,8bit的会导致Color Copied Images8,让CPU多运算了。

    Color Misaligned Images

    Misaligned Image表示要绘制的点无法直接映射到频幕上的像素点,此时系统需要对相邻的像素点做anti-aliasing反锯齿计算,增加了图形负担,通常这种问题出在对某些View的Frame重新计算和设置时产生的。

    很简单,不要出现image sizeimageView size不同的情况,这样会触发反锯齿计算,增加性能损耗。

    上demo:

    demo

    一下就好看出来,下面的图片尺寸不合适。

    所以,实际开发中,本地的图片比较好把控,只需要写好对应的尺寸就好了,但是对于download下来的图片,可以在加载完后进行size处理,以满足imageView frame。特别是对于很多app,有大量的tableview,如果进行处理,则会大幅度提高流畅度。

    Color Offscreen-Rendered

    最后就是Offscreen-Rendered(离屏渲染)了。

    这个东西讲起来感觉非常复杂,我觉得只需要知道,离屏渲染会导致CPU在后台保存一份bitmap,所以会导致CPU多余运算。

    而避免的方式则是避免去做触发的动作:

    • 重写drawRect方法
    • masksToBounds
    • 其他一些手动触发离屏渲染的动作

    最后看个demo:

    万恶的圆角 发现罪恶

    如图所示,触发了离屏渲染。

    总结:

    如果开发阶段都注意到这些细节,那么我觉得性能将不会是很大的问题了。

    相关文章

      网友评论

      • 03dbd3eed797:想问一下作者,怎么验证 CPU 和 GPU 是做了多余的运算的呢,怎么去查看运算的时间对比呢?
      • aa676c2b66ca:才发现模拟器还有这四个选项 :innocent: 打开离屏渲染,整个模拟器都黄了 :joy:
      • 515203f1d6bc:作者你好 关于图片32bit和64bit的问题 可能在iOS8.0以前 会有这个问题,但是在8.0以后 这种情况已经不太明显了,我想问一下你是怎样验证这个问题的,有没有分析数据出来
        kuailejim:@塔罗 只是理论 并没有去跑数据
      • xlL503721:离屏渲染不是导致增加CPU的载荷,是导致了GPU的载荷,在解决离屏幕渲染时都是用CPU去分担GPU的工作去解决问题的
      • Colin_狂奔的蚂蚁:作者您好,有个疑问需要向你请教一下,对于Color Copied Images,你说iOS最好用32bit的图片颜色格式,我测试的结果是:8bit的内存占12%,16bit的内存占15%,32bit的图片用ps无法导出,不知道iOS是否真的适合32bit图片颜色格式?
        kuailejim:@狂奔蚂蚁 这是个权衡点 但是大部分app都是32bit的
        Colin_狂奔的蚂蚁:@kuailejim 那不是很占空间?
        kuailejim:@狂奔蚂蚁 32bit的图PS是可以产生的,bit越大,图片所占的空间越大。
      • zyg:已阅~
      • VictoryForYou:离屏渲染 我觉得很难做到(对于需要'CG'画出来的东西啊)我就想知道 用drawRect方法是不是应该适当使用而不是完全禁止
        VictoryForYou:@kuailejim 精辟
        kuailejim:@VictoryForYou 任何优化只是针对可以优化的地方 优化的前提是实现功能
      • FengxinLi:请问一下楼主,有点绿色的那个是不就是Color Blended Layers,而黄色的就是提示有离屏渲染?
        我叫大大虾米:@kuailejim 刚看了下自己的app ,cell中的UILable 控件都是红色的
        kuailejim:@我叫大大虾米 你说的对
        我叫大大虾米:@Fengxinliju 应该是红色的吧
      • 鼻毛长长:想多了解一点李萍渲染的东西
        44468e02ac50:@Martin_wjl 哈哈
        Joy___:@鼻毛长长 李萍是谁 :smiley:
        kuailejim:@鼻毛长长 可以多去看看wwdc视频:smile:

      本文标题:浅谈iOS中的视图优化

      本文链接:https://www.haomeiwen.com/subject/bxtzlttx.html