内容简介:手机性能优化的重点,就是界面渲染。一般,计算任务都交给服务端。界面渲染慢,就不好了。常见的离屏渲染代码: 绘制阴影,
手机性能优化的重点,就是界面渲染。一般,计算任务都交给服务端。
界面渲染慢,就不好了。
常见问题,就是离屏渲染。 这里用 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 把文本放进去 ),离屏渲染这就开始了。
这个上下文缺信息,不在屏幕上, 不是帧缓冲。(渲染出来的图形上下文,不属于当前帧)。
之前 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 里了,可以直接使用。
真机运行直接选择,
本文 Demo 使用的是 500 px 的 API .
调试界面的离屏渲染,用的是 Color Offscreen-Rendered Yellow
选项。
调试目标是,出现大片的绿色。
这里可以用 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) } 复制代码
用背景色处理掉混色。
界面图层混色,就是多个视图的位置有重叠,他们又不是透明的。重叠区域的每一个像素,GPU 需要算出一种新的颜色(混色)。 如果这种效果,不是 UI 设计的,尽量避免。
调试界面的图层混色,用的是 Color Blended Layer
选项。
UILabel 建议设置背景色。UILabel 有文字,那就不透明,Label 默认的背景色是透明色,与父视图的背景色,混杂了。GPU 对相关位置的颜色,需要重新计算。
override func awakeFromNib() { super.awakeFromNib() [userNameLabel, photosLikeLabel, photosDescriptionLabel, photoTimeIntevalSincePostLabel].forEach { $0?.backgroundColor = UIColor.white } } 复制代码
设置后, 效果明显
混色,如果不是 UI 指定的效果,建议处理掉。
界面图层混色,常见的影响因素是 view 的 alpha 属性。 alpha 小于 1, 一般自带混色效果。
相关代码: github.com/BoxDengJZ/I…
其他知识点介绍: 卡顿(丢帧)。
Instruments 的 Core Animation 模版的时间线,就是 FPS. 显示随着时间,App 的帧率波动。
可以方便的读取帧数,直观的了解那些界面要改善。
用代码检测卡顿,自然是 CADisplayLink ,网上相关博客很多。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解C#(第3版)
斯基特 (Jon Skeet) / 姚琪琳 / 人民邮电出版社 / 2014-4-1 / 99.00元
本书是世界顶级技术专家“十年磨一剑”的经典之作,在C#和.NET领域享有盛誉。与其他泛泛介绍C#的书籍不同,本书深度探究C#的特性,并结合技术发展,引领读者深入C#的时空。作者从语言设计的动机出发,介绍支持这些特性的核心概念。作者将新的语言特性放在C#语言发展的背景之上,用极富实际意义的示例,向读者展示编写代码和设计解决方案的最佳方式。同时作者将多年的C#开发经验与读者分享,读者可咀其精华、免走弯......一起来看看 《深入理解C#(第3版)》 这本书的介绍吧!