iOS卡顿原因与优化
iOS卡顿原因与优化
1. 卡顿简介

卡顿: 指用户在使用过程中出现了一段时间的阻塞,使得用户在这一段时间内无法进行操作,屏幕上的内容也没有任何的变化。
卡顿作为App的重要性能指标,不仅影响着用户体验,更关系到用户留存、DAU等重要产品数据。因此,需要关注APP的卡顿
2. 卡顿产生的原因
首先,屏幕上看到的所有内容都是计算机绘制出来的图像
帧率:Frames Per Second(fps),表示每秒渲染帧数,
通常用于衡量画面的流畅度,每秒帧数越多,则表示画面越流畅。
通常,60fps比较流畅,也就是60张/秒,每张图片需要的渲染时间大约是:
1s/60张 = 1000ms/60张 = 16.7ms/1张
也就是1张图像在16.7ms内出现一次,就不会造成卡顿现象。


- CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等
- GPU 进行变换、合成、渲染,把渲染结果提交到帧缓冲区去,在下一次 VSync 信号到来时显示到屏幕上

卡顿产生的原因:当单位时间内,界面要刷新的时候,CPU或GPU由于计算量大,没有做好准备,
就会造成界面显示前一个时间段的界面,从而造成卡顿、掉帧现象
3. 如何避免卡顿
核心: 减少CPU、GPU的资源消耗
CPU
- 创建对象:对象的创建会分配内存、调整属性,因此,尽量使用轻量级的对象
- 布局计算:视图布局的计算是 App 中最为常见的消耗 CPU 资源的地方,不要频繁的调用UIView的相关属性;尽量提前计算好布局,在有需要时一次性调整到对应的属性,不要多次、频繁的计算和调整这些属性
- 线程处理:控制一下线程的最大并发数量;尽量把耗时的操作放到子线程,包括:文本计算、布局计算、图片的解码编码
GPU
- 尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示
- GPU能处理的最大纹理尺寸是4096x4096,一旦超过这个尺寸,就会占用CPU的资源进行处理,所以纹理尺寸尽量不要超过这个尺寸
- 尽量减少视图数量和层次
- 减少透明的视图(alpha<1),不透明的就设置opaque为YES
- 尽量避免出现离屏渲染
在OpenGL中,GPU有2种渲染方式:
1 当前屏幕渲染:在当前用于显示的屏幕缓冲区进行渲染操作
2 离屏渲染:在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作
离屏渲染消耗性能的原因?
- 需要创建新的缓冲区
- 离屏渲染的整个过程,需要多次切换上下文环境,先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,又需要将上下文环境从离屏切换到当前屏幕
哪些操作会触发离屏渲染?
- 光栅化,layer.shouldRasterize = YES
- 遮罩,layer.mask
- 圆角,同时设置layer.masksToBounds = YES、layer.cornerRadius大于0考虑通过CoreGraphics绘制裁剪圆角,或者叫美工提供圆角图片
- 阴影,layer.shadowXXX,如果设置了layer.shadowPath就不会产生离屏渲染
4. 卡顿检测
- 监控FPS
- 监控RunLoop
- ping主线程
4.1 监控FPS
帧率:Frames Per Second(fps),表示每秒渲染帧数

使用系统CADisplayLink监控,CADisplayLink是一个与屏幕刷新率相同的定时器,大约1/60s调用一次。
将其注册到RunLoop里面,计算当前画面的帧数。
delta为时间差等于1

4.2 监控RunLoop
由于UI刷新只能在主线程操作,因此,平时所说的“卡顿”,主要是因为主线程执行了比较耗时的操作
因此,可以添加observer到主线程Runloop中,通过监听Runloop状态切换的耗时,以达到监控卡顿的目的

RunLoop在BeforeSources和AfterWaiting后会进行任务的处理。可以在此时阻塞监控线程并设置超时时间,若超时后RunLoop的状态仍为RunLoopBeforeSources或AfterWaiting,表明此时RunLoop仍然在处理任务,主线程发生了卡顿

4.3 子线程Ping主线程
ping是常用的网络测试工具,用来测试数据包能否到达ip地址。

ping主线程的核心思想是向主线程发送一个信号,一定时间内收到了主线程的回复,即表示当前主线程流畅运行。
没有收到主线程的回复,即表示当前主线程在做耗时运算,发生了卡顿。
子线程Ping主线程的实现思路:
- 创建一个子线程进行循环检测,每次检测时设置标记位为YES
- 然后派发任务到主线程中将标记位设置为NO。
- 接着子线程休眠设定的阈值,判断标志位是否成功设置成NO,如果没有说明主线程发生了卡顿。
相当于:
子线程设置一个标识YES
如果发生了主线程的卡顿,那么到规定时间,主线程内的代码没有执行,则标识还是YES,这时候,代表卡顿
如果没有发生卡顿,那么到规定时间,主线程内的代码执行,则表示变为NO,这时候,代表没有发生卡顿

总结

相关文章:
iOS卡顿原因与优化
iOS卡顿原因与优化 1. 卡顿简介 卡顿: 指用户在使用过程中出现了一段时间的阻塞,使得用户在这一段时间内无法进行操作,屏幕上的内容也没有任何的变化。 卡顿作为App的重要性能指标,不仅影响着用户体验,更关系到用户留…...
关于synchronized介绍
synchronized的特性 1. 乐观锁/悲观锁自适应,开始时是乐观锁,如果锁冲突频繁,就转换为悲观锁 2.轻量级/重量级锁自适应 开始是轻量级锁实现,如果锁被持有的时间较长,就转换成重量级锁 3.自旋/挂起等待锁自适应 4.不是读写锁 5.非公平锁 6,可重入锁 synchronized的使用 1&#…...
NCDA设计大赛获奖作品剖析:UI设计如何脱颖而出?
第十二届大赛简介 - 未来设计师全国高校数字艺术设计大赛(NCDA)开始啦!视觉传达设计命题之一: ui 设计,你想知道的都在这里。为了让大家更好的参加这次比赛,本文特别为大家整理了以往NCDA大赛 UI 设计的优秀获奖作品&a…...
软考中级 软件设计师备考经验
考试介绍 软考中级的软件设计师需要考两个部分,选择题和大题,每科满分75,需要在同一次考试中两科同时大于等于45分才算通过。考试的内容包括计算机组成原理、数据结构、数据库、专业英语、信息安全、计算机网络等,范围比较广但考…...
Python猜数字小游戏
下面这段代码是一个简单的数字猜测游戏,其中计算机已经提前计算出了414 // 23的结果并存储在变量num中。然后,程序会提示用户来猜测这个结果。 以下是代码的主要步骤和功能: 初始化: num 414 // 23:计算414除以23的整…...
SQL面试题(2)
第一题 创建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…...
python常用pandas函数nlargest 和 nsmallest及其手动实现
pandas是Python数据分析的重要工具之一,提供了大量便捷的数据操作方法。nlargest和nsmallest是pandas中两个非常实用的函数,它们可以帮助我们快速找出Series或DataFrame中最大或最小的n个值。 ### pandas中的nlargest和nsmallest函数 - nlargest(n, colu…...
第六课:NIO简介
一、传统BIO的缺点 BIO属于同步阻塞行IO,在服务器的实现模型为,每一个连接都要对应一个线程。当客户端有连接请求的时候,服务器端需要启动一个新的线程与之对应处理,这个模型有很多缺陷。当客户端不做出进一步IO请求的时候,服务器…...
在vue2中使用饼状图
1.引入vue2和echarts <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> <script src"https://cdn.jsdelivr.net/npm/echarts5.4.0/dist/echarts.min.js"></script> 2.1 补充基本的body内容 <div id…...
面经(五)南京 软通动力 一面
注:已经有了接近一年的工作经验 总体评价 不完全是技术面,面试经过还行,但可能是期望岗位和对方需求不太一致,感觉不太好过 面试经过 HR找你,发简历入库,然后商量面试时间,发腾讯会议链接腾…...
线段树模型及例题整理
线段树的应用范围非常广,可以处理很多与区间有关的题目。 将区间抽象成一个节点,在这个节点中储存这个区间的一些值,那么如果看成节点的话,这就很像一棵满二叉树,所以我们可以用一维数组来储存节点。那么就要考虑父子节…...
揭秘Java性能调优的层次 | 综合多方向提升应用程序性能与系统高可用的关键(架构层次规划)
揭秘性能调优的层次 | 综合多方向提升应用程序性能与系统的高可用 前言介绍调优层次调优 — 设计案例说明 - 操作轮询控制事件驱动 调优 — 代码案例说明 - ArrayList和LinkedList性能对比案例说明 - 文件读写实现方式的性能对比 调优 — JVMJVM架构分布JVM调优方向**JVM垃圾回…...
事件循环解析
浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后&…...
物联网技术助力智慧城市安全建设:构建全方位、智能化的安全防护体系
一、引言 随着城市化进程的加速和信息技术的迅猛发展,智慧城市已成为现代城市发展的重要方向。在智慧城市建设中,安全是不可或缺的一环。物联网技术的快速发展为智慧城市安全建设提供了有力支持,通过构建全方位、智能化的安全防护体系&#…...
mac打不开xxx软件, 因为apple 无法检查其是否包含恶意
1. 安全性与隐私下面的允许来源列表,有些版本中的‘任何来源’选项被隐藏了,有些从浏览器下载的软件需要勾选这个选项才能安装 打开‘任何来源’选项 sudo spctl --master-disable 关闭‘任何来源’选项 sudo spctl --master-enable...
《深入浅出红黑树:一起动手实现自平衡的二叉搜索树》
一、分析 1. 红黑树的性质 红黑树是一种自平衡的二叉搜索树,它具有以下五个性质: (1)节点是红色或黑色。 (2)根节点是黑色。 (3)所有叶子节点(NIL节点)是…...
C++——模版
前言:哈喽小伙伴们好久不见,这是2024年的第一篇博文,我们将继续C的学习,今天这篇文章,我们来习一下——模版。 目录 一.什么是模版 二.模版分类 1.函数模版 2.类模板 总结 一.什么是模版 说起模版,我们…...
《TCP/IP详解 卷一》第9章 广播和组播
目录 9.1 引言 9.2 广播 9.2.1 使用广播地址 9.2.2 发送广播数据报 9.3 组播 9.3.1 将组播IP地址转换为组播MAC地址 9.3.2 例子 9.3.3 发送组播数据报 9.3.4 接收组播数据报 9.3.5 主机地址过滤 9.4 IGMP协议和MLD协议 9.4.1 组成员的IGMP和MLD处理 9.4.2 组播路由…...
备战蓝桥杯---动态规划的一些思想1
话不多说,直接看题: 目录 1.双线程DP 2.正难则反多组DP 3.换个方向思考: 1.双线程DP 可能有人会说直接贪心:先选第1条的最优路径,再选第2条最优路径。 其实我们再选第1条时,我们怎么选会对第2条的路径…...
基于BERTopic模型的中文文本主题聚类及可视化
文章目录 BERTopic简介模型加载地址文本加载数据处理BERTopic模型构建模型结果展示主题可视化总结BERTopic简介 BERTopic论文地址:BERTopic: Neural topic modeling with a class-based TF-IDF procedure BERTopic是一种结合了预训练模型BERT和主题建模的强大工具。它允许我…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
