简介
iOS卡顿监控有多种不同的计划和指标,在实施本钱和指标精确度上各有不同。本文例举一下常见的计划和代码,以及其指标的完成和拟合程度。
FPS
帧率
FPS数据,依据页面信息做聚合,或者APP版别之间比对,通常用于页面功能衡量。
单一的FPS数据难以用于卡顿的断定。
掉帧率
当时主流设备屏幕遍及在60帧,新iOS设备和部分Android设备有很多在90和120帧,核算掉帧率有更好的扩展性。
帧率动摇
对于游戏等APP的卡顿监控,虽然任天堂Switch只有30帧的锁帧,可是玩家也不会感觉到卡顿,可是过快的帧率动摇却会导致肉眼可见的卡顿。
帧率过低当然会导致卡顿,可是帧率动摇过快也是导致卡顿的原因。我们可以从帧间耗时,与前几帧帧间耗时的对比核算,得到帧率动摇水平。
一起满意两条件,则认为是一次卡顿Jank.
①Display FrameTime>前三帧平均耗时2倍。
②Display FrameTime>两帧电影帧耗时 (1000ms/24*2=84ms)。
一起满意两条件,则认为是一次严峻卡顿BigJank.
①Display FrameTime >前三帧平均耗时2倍。
②Display FrameTime >三帧电影帧耗时(1000ms/24*3=125ms)。
场景化
低FPS在一些场景下,才干表示页面正在产生卡顿,在页面停止的情况下,低FPS值并不能代表卡顿。
主要场景
-
页面转场
-
Scrollview等滑动
-
其他
- 容器内滑动
- 视频播放
监听页面生命周期的状况,观察页面是否处于转场中。
监听Runloop状况,观察页面是否处于滑动中。
Runloop
基于Runloop的卡顿监控,主要是判断除Runloop Waiting外的activity履行是否超出阈值时刻。
iOS-Matrix中阈值时刻默认值为2秒,卡顿检测间隔为1秒。
完成计划
- Observer
- Ping-Pong
Hitch Time Ratio
Instruments中当时运用该指标衡量卡顿,是指卡顿的时刻占总时刻的占比
量化卡顿的两种方法:
- 卡顿时刻:某一帧展示的时刻比预期的时刻晚了多少
- 卡顿率:总的卡顿时刻/总时刻
规范引荐:
Critical >= 10ms/s
Warning 5..10ms/s
Good < 5ms/s
烘托流程
把显现分为了提交和烘托2个阶段
辅助信息
页面信息
获取页面栈顶部的页面,部分特别页面需求做处理
@objc open class dynamic func topMost(of viewController: UIViewController?) -> UIViewController? {
// presented view controller
if let presentedViewController = viewController?.presentedViewController {
return topMost(of: presentedViewController)
}
// UITabBarController
if let tabBarController = viewController as? UITabBarController,
let selectedViewController = tabBarController.selectedViewController {
return topMost(of: selectedViewController)
}
// UINavigationController
if let navigationController = viewController as? UINavigationController,
let visibleViewController = navigationController.visibleViewController {
return topMost(of: visibleViewController)
}
// UIPageController
if let pageViewController = viewController as? UIPageViewController,
pageViewController.viewControllers?.count == 1 {
return topMost(of: pageViewController.viewControllers?.first)
}
return viewController
}
仓库信息
仓库信息需求做符号化解析,才干从函数地址解析成函数符号。可以参阅我的其他文章。
因为卡顿监控的滞后性,发现卡顿产生的时刻,仓库可能现已改变。通常仓库的获取并不能直接运用卡顿产生时刻的仓库,需求运用循环行列等方法,从之前记录的一组仓库中核算最近最耗时函数地点的仓库。
最近最耗时函数
经过核算之前一组仓库中重复次数最多的栈顶函数,找到其地点的仓库,才干正确反响卡顿产生时的仓库信息。
火焰图
获取之前产生的一组仓库信息,把主线程仓库组上报到对应渠道,即可把完成火焰图显现出来。火焰图可以可视化的显现最近最耗时函数信息,而且并非必定需求是最近最耗时的栈顶函数。
问题
iOS常见卡顿问题总结
- NSUserDefaults:低内存的情况下,体系复制内存数据到磁盘
- I/O:文件读写、数据库操作
- 体系接口:获取mac地址、切换音频设备、读取桌面icon未知数
- 死锁以及锁的乱用
- 排版制作:sizeWithFont、[EAGLContext setCurrentContext:]
- GCD并发行列短时刻创建大量使命
- UIWebview初始化、毁掉(运用功能更优的WKWebView)
引证
Matrix-iOS 卡顿监控
【PerfDog专家课堂】APP&游戏需求关注Jank卡顿吗?
Explore UI animation hitches and the render loop