iOS 性能检测新方式​——AnimationHitches

简介: iOS 性能检测新方式​——AnimationHitches

作者| 岚遥

image.gif

AnimationHitches 的运行原理



背景


在 Xcode12 中,Instrument 新增 AnimationHitches 检测类型用以检测卡顿,并去除 CoreAnimation 检测方式。在支持 PromotionDisplay 的设备上帧率可调整至 120 帧,并且会根据当前用户手势和设备状态进行动态调整。此时再继续使用帧率来判断性能的好坏及流畅度将会是一个错误的选择。所以 AnimationHitches 主要用于代替帧率检测,并且提出 卡顿时间比(Hitch Time Ratio) 的概念用于替代 FPS。由于目前关于 Hitch 相关的资料很少,而在 iPhone13Pro 之前 iPhone 屏幕最高刷新频率仍为 60 HZ,所以很多同学都还未关注到该能力。所以本篇将主要介绍 Hitch(卡顿) 的概念、RenderLoop(渲染循环) 的整体流程,卡顿类型及如何避免卡顿。


什么是卡顿?


 概念


任何时候屏幕上出现晚于预计的帧都属于卡顿。

1.jpg

 实例


例如 滚动动画(Scroll)、点击动画(Animation)、转场动画(Transition),这些流畅的动画构建了一种用户和屏幕内容的视觉连接感,而如果动画卡顿会导致动画画面跳跃,打破这种连接感,用户体验会变得很差。2.jpg

布局阶段


在布局阶段, layoutSubviews 会被所有需要布局的 View 调用。比如布局视图(frame、bounds、transform),增加或移除视图,亦或是直接调用 setNeedsLayout。注意这些布局操作并非立即执行,系统会合并这些布局请求,在 Runloop 休眠前统一执行这些操作。


显示阶段


在显示阶段,drawRect 会被每个需要被更新的 View 调用。比如 UILabel、UIImageView 或者只是任何重写 drawRect 方法的类。他们必须调用 setNeedsDisplay 用以支持 View 的更新。在绘制时每个自定义的绘图图层都会接收到带纹理的 CoreGraphics 的背景。他们将利用 CoreAnimation 进行绘制,这些图层就变成了图片。所以如果没有必要则不要重写 drawRect 方法,其不仅会额外开辟一块内存用以存储 bitmap,还会在 CPU 上进行绘制,增加了整体主线程时间占用,当自定义 drawRect 视图较多时,对整体的内存压力也比较大。

3.jpg

准备阶段


在 Prepare 阶段还没有解码的图像将会在这一步进行解码,也就是我们需要优化的常见的图片主线程解码操作。


对于每个被解码的图像, App 可能会持续存在大量的内存分配。这种内存分配与输入图像的大小成正比,而与 FrameBuffer 中实际渲染的图像视图的大小没有必然联系。当 App 占用越来越多的内存时,操作系统将会开始压缩物理内存(physical memory)。整个过程都需要 CPU 的参与,所以除了我们自己的 App 对 CPU 的使用外,还可能会增加无法控制的全局 CPU 使用率。最终,我们的 App 可能会消耗更多的物理内存,以至于操作系统需要启动终止进程,它将从低优先级的后台进程开始。如果我们的 App 对内存的消耗了达到了特定数量,可能会被终止,这也就是为什么经常会因为大图的原因产生 OOM。


若某个图像的颜色格式 GPU 无法直接使用,也会在这一步进行格式转换。这就要求对该图像进行 copy 操作,而不是直接使用指针,这样会耗时更长及占用更多的内存。


提交阶段


在提交阶段中,视图树将会被递归打包并发送到 RenderServer 中,所以当视图层级较为复杂时,这个过程耗费的时间也会更长一些,所以需要尽量减轻视图层级结构。


  • RenderServer


RenderServer 负责将我们的图层树转换为真正可显示的图像。RenderServer 有两个阶段:Prepare 和 Execute 。在 Prepare 阶段我们的图层树被编译成一系列简单的指令,供 GPU 执行,帧动画也在此处进行处理。在渲染执行阶段 GPU 将 App 的图层绘制成最终图像。

总结


本篇主要讨论了 RenderLoop 以及新的一帧展现给用户的整个流程,并且着眼于什么是卡顿,以及它的两种类型:提交卡顿以及渲染卡顿。并最终定义了卡顿时间比用以测量当前 App 的卡顿程度和性能。相信大家对整个渲染循环和卡顿类型有了更清晰的认识,在日常编码中也可以尽量避免这些问题。


本篇主要介绍了一些原理相关的概念,那么具体的卡顿应该如何测量?下一篇将会通过实践结合 Instrument 的 AnimationHitches 能力分析 DXSDK 作为卡片层面在日常信息流的使用过程中在性能方面存在的一些问题,以及 DXSDK 上半年做的一些性能优化改进。

相关文章
|
14天前
|
监控 算法 iOS开发
深入探索iOS函数调用栈:符号化与性能调优实战
在iOS开发中,理解函数调用栈对于性能调优和问题排查至关重要。函数调用栈记录了程序执行过程中的函数调用顺序,通过分析调用栈,我们可以识别性能瓶颈和潜在的代码问题。本文将分享iOS函数调用栈的基本概念、符号化过程以及如何利用调用栈进行性能调优。
34 2
|
5月前
|
传感器 安全 Android开发
探索iOS与安卓应用开发的性能差异
在移动操作系统领域,iOS和安卓的较量从未停歇。本文将深入探讨两大平台在应用开发中的性能表现,揭示它们各自的优势与局限。通过对比分析,我们将理解开发者如何在这两个不同的生态系统中做出权衡,以及这些选择如何影响最终用户的体验。
35 0
|
6月前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
280 0
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
2月前
|
安全 Android开发 数据安全/隐私保护
安卓与iOS的对决:移动操作系统的性能与创新
在当今智能手机市场,安卓和iOS两大操作系统一直处于竞争状态。本文将深入探讨它们在性能、安全性和用户体验方面的不同,并分析这些差异如何影响用户的选择。
56 3
|
5月前
|
编解码 安全 Android开发
探索iOS与Android开发的差异:从界面到性能
【6月更文挑战第10天】在移动应用开发的广阔天地中,iOS和Android两大平台各占山头,它们在设计理念、用户体验、性能优化等方面展现出独特的魅力。本文将深入探讨这两大系统在开发过程中的主要差异,从用户界面设计到性能调优,揭示各自背后的技术逻辑与创新策略,为开发者提供全面的视角和实用的开发指南。
|
6月前
|
监控 测试技术 iOS开发
查看ios 应用程序性能
查看ios 应用程序性能
80 0
|
6月前
|
监控 API iOS开发
克魔助手 - iOS性能检测平台
众所周知,如今的用户变得越来越关心app的体验,开发者必须关注应用性能所带来的用户流失问题。目前危害较大的性能问题主要有:闪退、卡顿、发热、耗电快、网络劫持等,但是做过iOS开发的人都知道,在开发过程中我们没有一个很直观的工具可以实时的知道开发者写出来的代码会不会造成性能问题,虽然Xcode里提供了耗电量检测、内存泄漏检测等工具,但是这些工具使用效果并不理想(如Leak无法发现循环引用造成的内存泄漏)。所以这篇文章主要是介绍一款实时监控app各项性能指标的工具,包括CPU占用率、内存使用量、内存泄漏、FPS、卡顿检测,并且会分析造成这些性能问题的原因。
|
6月前
|
监控 Linux iOS开发
如何使用克魔开发助手优化iOS应用性能
如何使用克魔开发助手优化iOS应用性能
70 1
|
存储 iOS开发
iOS主线程耗时检测方案
找出那个拖后腿的凶手
232 1
iOS主线程耗时检测方案
|
iOS开发
iOS UIDevice & 屏幕旋转检测
iOS UIDevice & 屏幕旋转检测
51 0