iOS显示性能优化过程讲解

点我跳转原文地址

logo.png

卡顿的原理

iOS系统界面滑动流畅性的保持主要是依靠CPU和GPU两大处理硬件间通力合作的结果,一个视图的显示需要先经过CPU创建、布局计算、对图片解码、文本绘制,然后CPU将计算的结果交给GPU,GPU可能需要对图形进行变换、合成、渲染,GPU然后将渲染的结果提交到帧缓冲区等待下一次的垂直同步信号(V-Sync)到来显示到显示器上,如果在一个V-Sync间隔内CPU或者GPU由于过高的利用率都可能导致数据的不及时提交,那么那一帧数据就会被丢弃,等待下一次的V-Sync再显示,这也就是通常能感受到的界面卡顿现象,也就是掉帧。

优化过程

所以当出现卡顿现象时主要去分析此刻CPU和GPU的利用率,当出现较高的CPU利用率时应及时去分析代码执行的效率,或者用Time Profier去分析导致较高占用率的代码,更多详细的关于优化CPU的情况本文不做详细分析。
而对于GPU资源消耗的优化本文将通过一个Demo优化过程来讲解优化的步骤,你可以在这里GitHub下载源码,Demo是有2个tab组成的,before是优化前视图,after是优化后的,你可以通过对比学习体会其中的差异。
下载运行demo, 打开Xcode的调试选项,在菜单栏-Debug-View Debugging-Rendering可以找到,运行APP(真机)勾选相关的菜单选项即可
Rendering.png

1.视图混合(Blending)

app中显示的效果往往是多个视图重合叠加的效果,而在计算视图重合显示颜色的时候就需要考虑透明的影响,当顶部视图出现透明的情况时,颜色的计算就需要考虑其透明度,这样无疑增加了计算成本,消耗GPU资源,所以应尽量避免过多的透明视图数量。
对于UIImageView而言,如果图片本身是带有透明通道的同样会导致Blending,所以应该尽量避免使用带有透明度的图片。
对于文本UILable, 如果不设置背景颜色,同样会出现Blending,所以需要设置UILabel的背景颜色,对于显示中文的UILabel, 除了设置背景颜色外还需要设置masksToBounds属性,因为中文时UILable会多了一个sublayer。
勾选Rendering中的第一个选项Color Blended Layers,此选项就是用于检测哪些视图出现了Blending,出现Blending的地方会用红色标记出来,运行demo可以出现下图所示情况:
Blending.png

可以看到,before tab下的控制器视图无论是图片还是文本都被标红,表示出现了Blending,对于图片我们可以在Assets里面找到对应的图片,然后查看简介就可以查看图片是否有Alpha通道,会看到图片都具有Alpha通道,也就回导致Blending
Alpha通道.png
对于这种情况,可以让UI切图时关闭此Alpha通道,也可以直接用mac自带的图片软件打开图片,然后导出图片关闭Alpha通道。所以我们需要将所有有Alpha的图片都处理一遍,尽量不要使用带有透明度的图片。
对于UILabel,上面有提到,我们只需要下面的2行代码即可处理:

titleLabel.backgroundColor = UIColor.white
titleLabel.layer.masksToBounds = true

通过去掉图片alpha通道优化后如下图所示,只有被设置为圆角的小图片还存在Blending,因为我们是直接设置的layer的cornerRadius(IOS9以下会导致离屏渲染),同样我们可以直接用无透明通道的圆角图片来替换解决,但这需要UI适配更多背景图片。
Blending优化后.png

2.光栅化

开启光栅化是通过设置属性shouldRasterize,开启光栅化后CALayer会被保存为bitmap放到缓存中,这样在下次需要时可以直接中缓存中取出来显示,这样节省了渲染时间,例如对于设置有阴影效果的复杂视图会对性能有一定的提升。

nameLabel.layer.shouldRasterize = true//开启光栅化

第二个调试选项 Color Hits Green and Misses Red就是用来查看光栅化视图的,勾选后若视图被标记为绿色,则表示命中了缓存,直接从缓存中取出来显示,缓存的有效时间为100ms, 而红色则表示没有命中。Demo中,我们对第2个Label开启了光栅化,滚动会发现被标记为绿色
光栅化.png

更新一个已光栅化的Layer会触发离屏渲染,所以选择哪些视图适合做光栅化需要根据场景权衡,光栅化适合那些布局复杂而不经常变动的视图,比如

  • 用于避免静态内容的复杂特效的重绘,例如UIBlurEffect
  • 用于避免多个View嵌套的复杂View的重绘。

同时注意缓存是有大小限制的,所以不要过度是使用光栅化,因为超过缓存大小会导致大量的离屏渲染。

3.颜色格式

Color Copied Images选项能标识出视图中不能被GPU处理的图片,因为来自网络的图片格式可能千变万化,有的图片的格式是GPU无法识别的所以会交给CPU处理,出现这种情况就需要修改图片格式,

4.不标准的表面颜色格式

Color Non-Standard Surface Formats 打开此选项后会发现Label会出现灰色的背景颜色,然后经过我们给Label设置了背景颜色后便消失了,关于此选项的相关介绍甚少,期待有人能挖掘挖掘,所以只能猜测,苹果推荐我们给Label设置一个背景颜色。
Non-Standard.png

5.颜色刷新频率

默认情况下图层的颜色更新是有10ms的延迟的,在某些特定情况下可能需要关闭这个延迟,但绝大多数情况用不到这个选项。

6.图片大小

Color Misaligned Images选项在图片像素不对齐(也就是图片带alpha通道)时,会在图片上面加一层洋红色来标识;而图片被缩放时,会加一层黄色来标识,我们可以看到优化前的图片会出现图片缩放,因为图片的显示大小和图片的大小不匹配。
Misaligned.png
图片缩放同样会消耗GPU资源,所以尽量保证图片的显示大小和原图大小一致来避免缩放,所以demo的图片在处理后大小都等于显示的大小来避免缩放。

7.离屏渲染

Color Offscreen-Rendered Yellow会用黄色标识哪些图层出现了离屏渲染,什么是离屏渲染?
离屏渲染表示渲染不是发生在当前屏幕的缓冲区中,而是发生在其他缓冲区的渲染,这就需要开辟更多的缓冲区,等到要用的时候再从其他的缓冲区读取来显示,所以这样会消耗更多的GPU资源,所以避免离屏渲染可以有效的提升显示性能。
离屏渲染.png
如上图所示,要显示一个相机图标和一个蒙层,在前两个渲染通道中,GPU分别得到了相机的纹理和蓝色的蒙版layer的渲染结果。但这两个渲染结果没有直接放入Frame Buffer中,这就是离屏渲染。等到第三个渲染通道,才把两者组合起来放入Frame Buffer中最终显示到屏幕上,这就是典型的离屏渲染。
运行demo,打开Color Offscreen-Rendered Yellow选项,在beforetab控制器视图下出现离屏渲染的图层便会被黄色标识出来,如图:
Offscreen.png
可以发现右边的大图出现了离屏渲染,而圆角的小图却没有,大图出现离屏渲染的原因是设置了shadow阴影,而因为测试机器是ios11所以设置图片的cornerRadius并不会导致离屏渲染。
同样设置了以下属性时,都会触发离屏渲染:

  • shouldRasterize(光栅化)
  • masks(遮罩)
  • shadows(阴影)
  • edge antialiasing(抗锯齿)
  • group opacity(不透明)
  • 复杂形状设置圆角等(ios8)
  • 渐变

上面出现离屏渲染的case都应该要注意,所以针对shadow可以通过设置shadowPath来避免,光栅化也应该尽量避免:
优化后代码如下:

        mainImageView.layer.shadowColor = UIColor.black.cgColormainImageView.layer.shadowOpacity = 1mainImageView.layer.shadowRadius = 2
//        mainImageView.layer.shadowOffset = CGSize(width: 2, height: 2)mainImageView.layer.shadowPath = UIBezierPath.init(roundedRect: mainImageView.bounds, cornerRadius: 2).cgPathsmallImageView.layer.cornerRadius = smallImageView.frame.size.width / 2smallImageView.clipsToBounds = truenameLabel.backgroundColor = UIColor.whitetitleLabel.backgroundColor = UIColor.whitetitleLabel.layer.masksToBounds = truenameLabel.layer.masksToBounds = true
//        nameLabel.layer.shouldRasterize = true

8.快速路径

第七个选项“Color Compositing Fast-Path Blue”用于标记由硬件绘制的路径,蓝色越多越好,demo略

9.变化区域

最后一个Flash Updated Regions 用于标记发生重绘制的区域并用黄色标记出来,对于大多数不变的区域应该尽量的避免重绘而只有小部分经常变化的区域重绘这有助于显著提高性能。demo略

优化结果

经过对图片Alpha透明度调整,大小剪裁适配显示,更改设置阴影,文本背景等一系列的优化,使用Core Animation记录GPU使用率的变化来观察优化效果:
before:
before.png
可以看到优化前CPU平均占用率达到60%,这还只是简单的视图布局,如果更加复杂占用率还会增加,这也就意味着更高的卡顿风险。

after:
after.png

对比可以发现在提升了平均显示帧数的同时大大降低了GPU消耗,性能得到显著的提升。

测试环境:Xcode9.3、iPhone6s、 iOS11、Swift4
Demo地址:GitHub地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.SoapUI接口测试--创建项目

1、点击File-->New soapUI Project 2、填写项目名称,接口服务地址后单击【OK】按钮后就成功创建了一个项目 3、模拟发送请求 4、创建请求 或者直接Copy一个请求 5、保存项目 6、项目是以xml的格式保存的,下次用的时候可以直接导入,点击Fil…

HTML图片元素(标记)

<html> <head> <title>第一个网页</title> </head> <body> ***************图片元素******************</br> <img srcmm.jpg /> </body> </html> 新建一个文件夹“text”,在text文件夹内新建index.html并放入一张…

ASP.NET Aries 3.0发布(附带通用API设计及基本教程介绍)

主要更新&#xff1a; 1&#xff1a;升级处理机制&#xff08;js请求由同步变更为异步&#xff09; 2&#xff1a;优化前端JS&#xff1a;包括API和配置方式。 3&#xff1a;增加InputDialog功能。 4&#xff1a;增远远程验证功能。 5&#xff1a;优化权限安全机制。 6&#xf…

甲骨文称 Java 序列化的存在是个错误,计划删除

甲骨文计划从 Java 中去除序列化功能&#xff0c;因其在安全方面一直是一个棘手的问题。 Java 序列化也称为 Java 对象序列化&#xff0c;该功能用于将对象编码为字节流...Oracle 的 Java 平台小组的首席架构师 Mark Reinhold 说&#xff1a;“删除序列化是一个长期目标&#x…

CreateProcess

Windows 进程创建完整过程&#xff08;除去细节&#xff09; 当前流程是分析WinXP x86得到的&#xff0c;在最新版本Windows上不一定正确&#xff0c;但是可以做一个参考&#xff0c; 由于我这里符号并不全&#xff0c;所以导致我这里有些东西看到的可能是错误的&#xff0c;误…

MVC架构模式(2)

简介&#xff1a; MVC最初是在Smaltalk_80中被用来构建用户界面的。M代表模型Model&#xff0c;V代表视图View&#xff0c;C代表控制器Controller。 Model模型层&#xff0c;可以简单理解就是数据层&#xff0c;用于提供数据。在项目中&#xff0c;&#xff08;简单理解&#x…

ios学习之旅---指针也不难

1、认识指针#include <stdio.h> //基本数据类型作为函数參数传递是值传递 //void moveFront(int x ,int y) //{ // x x 2; //} void test() {// 确定当前坐标int x 20;int y 150;printf("%p\n",&x);printf("%lu\n",&x);*((int *)(0…

符合skyline的3dml网络发布服务

技术交流群&#xff1a;665060698使用java web实现&#xff1b;接口符合skyline的3dml模型形式&#xff1b;通过简单的发布界面&#xff0c;直接发布3dml模型&#xff1b;实现te pro在客户端读取数据&#xff1b;实现在te pro客户端的对应查询功能&#xff1b;负载可以达到skyl…

51NOD 1125(交换机器最小代价) (贪心) 思想 !思想!

题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId1125 1125 交换机器的最小代价基准时间限制&#xff1a;1 秒 空间限制&#xff1a;131072 KB 分值: 80 难度&#xff1a;5级算法题收藏关注有N台机器重量各不相等&#xff0c;现在要求把这些机器按照…

《Python从小白到大牛》简介

《Python从小白到大牛》已经上市&#xff01; 本书是一部系统论述Python编程语言、OOP编程思想以及函数式编程思想的立体化教程&#xff08;含纸质图书、电子书、教学课件、源代码与视频教程&#xff09;。为便于读者高效学习&#xff0c;快速掌握Python编程方法。本书作者精心…

webpack学习

全局安装安装webapck npm i webpack -g 现在我们就可以全局的使用webpack命令了 webpack中基础的命令&#xff1a; webpack enter.js output.js --watch 这个命令是将enter.js打包成output.js&#xff0c;然后html只需要引用该文件就可以了看如下entry.js,这是简单的js代码。 /…

从ORA-27300,ORA-27301到ORA-00064

近期因为session数量添加&#xff0c;须要调整session&#xff0c;也就是要调整process參数。看是比較简单的一个问题&#xff0c;却遭遇了ORA-27300&#xff0c;ORA-27301。因为这个涉及到了有关内核參数kernel.sem的改动。以下是其详细描写叙述。1、故障现象OS版本号&#xf…

Halcon|读取3D相机点云数据

Halcon|读取3D相机点云数据 最近发现很多小伙伴在使用Halcon处理3D工业相机扫描结果的时候遇到了“如何读取”的问题。一般的3D工业相机储存数据的格式有txt格式、tif格式、csv格式、ply格式、ptx格式、bin格式、obj格式等。 txt格式 读取txt文件生成3D模型一般需要分析txt文件…

药片粘连物体的分割

药片粘连物体的分割要求&#xff1a;图片&#xff1a;处理程序&#xff1a;处理结果&#xff1a;要求&#xff1a; 将药片分割&#xff0c;统计药片数量。不能使用模板匹配。 图片&#xff1a; 先看一下要处理的原图&#xff1a; 处理程序&#xff1a; read_image (Image…

BZOJ 1026 [SCOI2009]windy数

1026: [SCOI2009]windy数 Description windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道&#xff0c;在A和B之间&#xff0c;包括A和B&#xff0c;总共有多少个windy数&#xff1f; Input 包含两个整数&#xff0c;A B。 Outp…

不连续区域的拟合

如下图&#xff0c;需要把图中4个半圆分别连接起来 我试过closing 和 dilation&#xff0c;下图中后三个还可以连接起来&#xff0c; 但是第一个因为不连续地方较长&#xff0c;如果增大closing的值&#xff0c;会导致其它点 出现过度畸形。 有没有能连接相邻选区的方法&#…

SPSS输出的结果都要写到文章中吗

SPSS输出的结果都要写到文章中吗 经常有人问到&#xff0c;SPSS输出的结果都要写到文章中吗&#xff1f;文章中应该写什么呢&#xff1f;比如&#xff0c;均值、中位数、众数、标准差、百分位数、最小值、最大值等等&#xff0c;都要出现在文章中吗&#xff1f;洋洋洒洒那么多&…

php Closure 类型

2019独角兽企业重金招聘Python工程师标准>>> <?php /*** Closure 理解* 匿名函数&#xff08;Anonymous functions&#xff09;&#xff0c;* 也叫闭包函数&#xff08;closures&#xff09;* Closure 是匿名函数的php中的称呼*/// 创建一个Closure$func funct…

ftk学习记(label篇)

【 声明&#xff1a;版权全部&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】还是接着上面的一篇博文。之前以前答应过大家&#xff0c;让大家看一下最简单的ftk程序是怎么执行的。所以&#xff0c;这里我们上传一下图片。由于…

扇形特征点提取

处理要求 分别找出扇形左上角&#xff0c;左下角&#xff0c;右上角&#xff0c;右下角&#xff0c;最高点&#xff0c;下面弓形最高点 原图 halcon 处理程序 read_image (Image14208259e49d7b1cf7c544, 544.bmp) rgb1_to_gray (Image14208259e49d7b1cf7c544, GrayImage) t…