iOSiOS开发

iOS性能优化 视图渲染

2021-11-23  本文已影响0人  _好久不见_

iOS性能优化的一个重要方面是视图渲染,在渲染的过程中避免出现图层混合,离屏渲染等问题,从而减少CPU和GPU的性能开销,达到性能优化的目的。

我们在开发调试过程中,可通过Xcode中的视图调试选项来帮助我们快速查找出渲染过程中的问题。
真机调试运行App项目,在Xcode的工具栏中选择,Debug -> View Debugging -> Rendering,其中有9个选项。

Xcode视图调试选项路径.png

若使用的是模拟器,在Simulator工具栏的Debug选栏中也有视图调试的选项。

Simulator视图调试选项路径.png
选项 说明
Color Blended Layers 图层混合,产生了图层混合视图上会标注为红色,没有发生图层混合视图上会标注为绿色。红色越多,性能越差。
Color Hit Green and Misses Red 光栅化,光栅化会将layer预先渲染成位图bitmap,然后被缓存,缓存未被复用则标注为红色,缓存被复用会标注为绿色。红色越多,性能越差。
Color Copied Images GPU 不支持的颜色格式的图片需要被复制到CPU进行颜色格式转换,因此这样的图片会被标注为蓝色。蓝色越多,性能越差。
Color Layer Formats 图层颜色格式, 暂不清楚。
Color Immediately 立即刷新, 通常以每10毫秒一次的频率更新图层调试颜色。选中这个选项则设置每帧画面都会刷新,在需要加快颜色刷新频率的场景下使用,通常情况下用不到。
Color Misaligned Images 图片错位,这个选项检查图片是否被缩放,以及像素是否对齐。被缩放的图片会被标记为黄色,像素不对齐则会标注为紫色。黄色、紫色越多,性能越差。
Color Offscreen-Rendered Yellow 离屏渲染,产生离屏渲染的图层会标注为黄色。黄色越多,性能越差。
Color Compositing Fast-Path Blue 快速路径,使用 OpenGL 绘制的图层会标注为蓝色。蓝色越多,性能越好。
Flash Updated Regions 重绘区域,进行了重绘的区域会标注成黄色,使用Core Graphics重新绘制会消耗性能,重绘区域越小越少,性能越好。

调试这几个选项,我们来具体看看,针对视图渲染有哪些具体问题需要优化。

Color Hit Green and Misses Red(图层混合)

在多个UI视图叠加的情况下,如果有透明或者半透明的控件,那么GPU会根据透明度去计算这些layer叠加在一起最终的显示的颜色。举例,如果顶层VeiwA颜色是红色RGB(255,0,0),透明度是40%,底层ViewB颜色是绿色RGB(0,255,0),那么最终叠加显示出来颜色是RGB(102,153,0)。
计算公式

RGB(混合) = RGB(A) * alpha + RGB(B) * (1-alpha)

这个渲染过程会消耗GPU性能,因此要避免出现图层混合。

顺便提一下:UIView的opaque属性默认为Yes。
opaque这个属性不是决定视图是否透明,而是决定在视图渲染过程的处理方式。视图是否透明跟 alpha 和 hidden 有直接关系。
如果视图不透明,就设置opaque为Yes,表示图形系统会将视图视为完全不透明,完全不透明视图应该使用完全不透明的内容来填充,该内容的alpha值应该为1.0(自身的alpha和填充颜色的alpha都应该为1.0),这样图形系统将不考虑它与其他视图的混合颜色计算,从而提高性能。若设置为NO,图形系统通常会将视图与其他内容合成,消耗性能。如果View是在scrollView中或者在动画中,对性能的提升更为明显。
有些View的子类使用drawRect:方法绘制自己的内容,那么opaque属性对其无效。

Color Hit Green and Misses Red(光栅化)

这个选项用来检测是否正确使用layer的shouldRasterize属性,该属性默认是NO,若 shouldRasterize为YES则开启光栅化。光栅化是将layer预先渲染成位图(bitmap),然后缓存起来,缓存未被复用则标注为红色,缓存被复用会标注为绿色,红色越多,性能越差。使用光栅化的视图清晰度会降低。

Color Copied Images (图片被复制)

苹果的GPU只解析32bit的颜色格式,32bit的颜色格式由RGBA(红、绿、蓝、透明度)四个颜色通道组成,每一个颜色通道都占据8bit,取值范围是[0, 255]。
如果某图片是GPU 不支持的颜色格式,那么图片需要被复制到CPU进行颜色格式转换,这样的图片会被标注为蓝色。蓝色越多,性能越差。

Color Layer Formats(图层颜色格式)

这个选项用来解析图层的颜色格式,具体用途暂不清楚。
打开这个选项后,UILabel都会被标注,标注为银白色或橙色,UIImageView的图片内容有部分透明时标注为紫罗兰色,全不透明时标注为橙色;有趣的是,xib中调整UILabel的textColor,当RGB三个颜色通道的色值一致时(如000000、999999、FFFFFF等),UILabel会被标注为银白色,当RGB三个颜色通道的色值不一样时(如999897等),UILabel会被标注为橙色。

Color Immediately(颜色刷新)

这个选项用来调整颜色刷新频率。通常情况是以每10毫秒一次的频率更新图层调试颜色,选中这个选项则设置每帧画面都会刷新,没有了10毫秒的延迟。在需要加快颜色刷新频率的场景下使用,通常情况下用不到。

Color Misaligned Images(图片错位)

这个选项用来检测图片在展示时是否被放大或缩小,以及像素是否对齐。如果image.size和imageView.size不匹配(例如,image的实际大小是50×50,imageView的尺寸大小25×25,或者为200×200),图片在展示时会缩放或者放大图片,会消耗资源,imageView会被标注为黄色,黄色越多,性能越差。避免出现黄色标注,将imageView.size设置成与image.size一样的。

Color Offscreen-Rendered Yellow(离屏渲染)

这个选项用来检测是会把那些离屏渲染的图层显示为黄色。黄色越多,性能越差。

屏幕渲染有 当前屏幕渲染 和 离屏渲染 两种方式。

常见的会引起离屏渲染的操作:

view.layer.shadowOffset = CGSizeMake(0, 2);
view.layer.shadowOpacity = 1;
view.layer.shadowRadius = 4;
view.layer.shadowPath = CGPathCreateWithRect(view.bounds, nil);
//或者
view.layer.shadowPath =UIBezierPath(view.bounds).CGPath;

Color Compositing Fast-Path Blue(快速路径)

这个选项用来检测是否是直接使用 OpenGL 绘制的, 使用 OpenGL 绘制的图层会标注为蓝色。蓝色越多,性能越好。如果仅仅使用 UIKitAPI,那么不会有任何效果。

Flash Updated Regions(重绘区域)

这个选项用来检测是否出现重新绘制,进行了重绘的区域会标注成黄色,使用Core Graphics重新绘制会消耗性能,因此重绘区域越小越少,性能越好。

上一篇 下一篇

猜你喜欢

热点阅读