1、渲染简介
正常渲染:APP中的数据经过CPU和GPU的计算处理后,形成帧数据并将结果存放在帧缓存区,需要显示时从帧缓存区拿取数据经过数模转换并渲染到屏幕上的过程(数据特点是即用即丢且只能存放一组数据)。
离屏渲染:APP需要显示的画面涉及到多个layer混合处理,因为帧缓存区只能存放一组数据无法同时对多组数据进行处理时,系统会自动将这多组的数据存放至离屏缓存区并混合处理后形成一组数据再重走正常渲染流程的过程。
2、离屏渲染的利弊
劣势:离屏渲染加大了系统的负担,造成性能上的损耗。主要表现在以下几个方面。
离屏渲染需要额外的存储空间,存储空间大小的上限是2.5倍的屏幕像素大小,一旦超过,则无法使用离屏渲染
一旦因为离屏渲染导致最终存入帧缓存区的时候,已经超过了16.67ms,则会出现掉帧的情况
优势:虽然离屏渲染会需要多开辟出离屏缓存区来存储中间状态,但是对于多次出现在屏幕上的数据,可以提前渲染好,从而达到复用的目的,这样CPU/GPU就不用做一些重复的计算(光栅化)。
开发的特殊需求背景下,比如 一些动画效果和显示效果,需要多图层以及离屏缓存区保存中间状态,这种情况下就不得不使用离屏渲染(圆角、阴影、高斯模糊等)。
3、离屏渲染监控
Xcode模拟器提供给开发者一个工具,可如下图进行开启,开启状态触发离屏渲染的视图会被标记颜色
4、日常开发避免非必要离屏渲染
日常开发时总是听到有人说尽量避免使用圆角来避免离屏渲染的问题产生。那么经过上文我们可以得知这一说法并不完全正确。
我们先看一下圆角方法cornerRadius的官方描述:
Setting the radius to a value greater than 0.0 causes the layer to begin drawing rounded corners on its background. By default, the corner radius does not apply to the image in the layer’s contents property; it applies only to the background color and border of the layer. However, setting the masksToBounds property to true causes the content to be clipped to the rounded corners.
设置cornerRadius大于0时,只会为layer的backgroundColor和border设置圆角,而不会对layer的contents设置圆角,除非同时设置了layer.masksToBounds为true(对应UIView的clipsToBounds属性)。
针对这一描述我们可以观看以下示例:
在界面上显示一个设置了图片的按钮,虽然显示时会涉及到按钮背景和图片的分别渲染,但是按钮视图显示到屏幕上时系统实质上是先将按钮背景渲染到屏幕上,然后再将图片渲染到屏幕上来实现这一按钮的正常现实的。所以并没有出现图层混合所以也不会出现离屏渲染现象。
当我们对按钮进行圆角切割时,这样按钮视图显示到屏幕上时系统必须要先将按钮背景色数据处理完成,然后在背景上添加图片数据,最后再对两组数据进行切割处理后才能形成有效的位图数据渲染到屏幕上。所以会出现图层混合也就会导致离屏渲染现象出现。
那么如何避免这一情况出现呢???
我们可以设置按钮背景色与父视图颜色相同,然后单独对按钮的图片进行切割就可以避免离屏渲染情况出现了。