iOS 性能优化思路:界面离屏渲染、图层混色

栏目: IOS · 发布时间: 6年前

内容简介:手机性能优化的重点,就是界面渲染。一般,计算任务都交给服务端。界面渲染慢,就不好了。常见的离屏渲染代码: 绘制阴影,

手机性能优化的重点,就是界面渲染。一般,计算任务都交给服务端。

界面渲染慢,就不好了。

常见问题,就是离屏渲染。 这里用 NSShadow 处理掉 CALayer 的阴影属性带来的离屏渲染。

常见的离屏渲染代码: 绘制阴影,

var label = UILabel()
        label.layer.shadowColor = UIColor.lightGray.cgColor
        label.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
        label.layer.shadowOpacity = 1.0
        label.layer.shadowRadius = 5.0
        label.text = "离屏渲染"
复制代码

写完以后,CPU 和 GPU 都没有充足的信息绘制阴影效果。

过程是, CPU 会先把文本传出去,请求 GPU (CPU 把文本传给 GPU ),创建一个内存中的位图上下文(GPU 把文本放进去 ),离屏渲染这就开始了。

这个上下文缺信息,不在屏幕上, 不是帧缓冲。(渲染出来的图形上下文,不属于当前帧)。

iOS 性能优化思路:界面离屏渲染、图层混色

之前 CPU 把文本处理好了,现在 CPU 处理文本效果(这里是阴影)。

然后,CPU 拿到渲染好的文字,基于渲染出来的每一个像素的透明度,计算出阴影的形状。

最后,CPU 把最新计算出来的文字阴影形状的信息,传给 GPU . GPU 有阴影信息,有之前图形上下文的渲染文本,GPU 就渲染好了最终的文字及其阴影,交给帧缓冲 (Frame Buffer), 我们就看到了。

这段代码要渲染两次,出现了离屏渲染。对 GPU 的性能有影响。他需要等待 CPU 来算出阴影的形状。

因为我们要 60 的帧数 ( FPS ), GPU 准备帧缓冲,渲染出当前帧,只有 17 毫秒的时间。拖累了主线程,屏幕刷新不过来。

对于图形阴影, 用 layer 的 shadowPath. 对于文字阴影,用 NSShadow .

layer 的四个属性 shadowColor , shadowOffset ,shadowOpacity ,shadowRadius ,一般性能不好。

对于一个视图框, 通过 layer 在周边加阴影。用 layer 的 shadowPath,创建一个 UIBezierPath,

UIBezierPath(rect: CGRect(x: 0, y: 0, width: 50, height: 50))
// size of your label
复制代码

与之前不同,图层不用渲染两次。现在 GPU 有了足够的信息绘制阴影效果, 就不用离屏渲染了。

对于文字阴影,用 NSShadow ,用 layer.path 就比较难。

UI 性能优化主要用的是 Instruments 的 Core Animation 模版。

过去,Core Animation 模版几个调试选项非常强大,正常的绿色, 异常的红色,离屏渲染的黄色。

(光栅化有效,光栅化后缓存的内容成功复用。界面会显示绿色。

光栅化失效的部分,呈红色。光栅化后缓存的内容没有复用,光栅化隐式创建的位图浪费了。直接重新绘制。 )

现在这些利器都在 Xcode 里了,可以直接使用。

真机运行直接选择,

iOS 性能优化思路:界面离屏渲染、图层混色

本文 Demo 使用的是 500 px 的 API .

调试界面的离屏渲染,用的是 Color Offscreen-Rendered Yellow 选项。

调试目标是,出现大片的绿色。

iOS 性能优化思路:界面离屏渲染、图层混色

这里可以用 Apple 的 UIKit 框架下的 NSShadow 对象。

let shadow = NSShadow()
            shadow.shadowColor = UIColor.lightGray
            shadow.shadowOffset = CGSize(width: 0.0, height: 5.0)
            shadow.shadowBlurRadius = 5.0
            if let mutableAttributedString = label.attributedText as? NSMutableAttributedString{
                let range = NSRange(location: 0, length: mutableAttributedString.string.count)
                mutableAttributedString.addAttribute(NSAttributedString.Key.shadow, value: shadow, range: range)
            }

复制代码
iOS 性能优化思路:界面离屏渲染、图层混色

用背景色处理掉混色。

界面图层混色,就是多个视图的位置有重叠,他们又不是透明的。重叠区域的每一个像素,GPU 需要算出一种新的颜色(混色)。 如果这种效果,不是 UI 设计的,尽量避免。

调试界面的图层混色,用的是 Color Blended Layer 选项。

UILabel 建议设置背景色。UILabel 有文字,那就不透明,Label 默认的背景色是透明色,与父视图的背景色,混杂了。GPU 对相关位置的颜色,需要重新计算。

iOS 性能优化思路:界面离屏渲染、图层混色
override func awakeFromNib() {
        super.awakeFromNib()
        [userNameLabel, photosLikeLabel, photosDescriptionLabel, photoTimeIntevalSincePostLabel].forEach {
            $0?.backgroundColor = UIColor.white
        }
}

复制代码

设置后, 效果明显

iOS 性能优化思路:界面离屏渲染、图层混色

混色,如果不是 UI 指定的效果,建议处理掉。

界面图层混色,常见的影响因素是 view 的 alpha 属性。 alpha 小于 1, 一般自带混色效果。

相关代码: github.com/BoxDengJZ/I…

其他知识点介绍: 卡顿(丢帧)。

Instruments 的 Core Animation 模版的时间线,就是 FPS. 显示随着时间,App 的帧率波动。

iOS 性能优化思路:界面离屏渲染、图层混色

可以方便的读取帧数,直观的了解那些界面要改善。

用代码检测卡顿,自然是 CADisplayLink ,网上相关博客很多。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Google模式

Google模式

Eric Schmidt、Jonathan Rosenberg / 李芳齡 / 天下雜誌出版社 / 2014-11-7 / TWD 420.00

上市即登紐約時報暢銷書、Amazon科技經營排行榜TOP1 未上市即售出美、英、德、日、荷等12國版權 Google創辦人Larry Page專文推薦 第一本由Google領導團隊人首度公開的企業內部運作與思維 Google董事會執行主席艾力克.施密特獨家揭露 Google從崛起到稱霸超過10年的管理與工作秘笈, 以及如何吸引21世紀最搶手的人才-智慧創做者(S......一起来看看 《Google模式》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具