一:卡顿
什么是Hang?
试想这样的场景:当用户在你的APP中进行交互时,APP却没有及时的响应用户的操作。
这种体验可以被描述为延时、慢、卡顿,在Apple开发中,我们称这种无响应的表现为Hang。
(温馨提示:本片内容来源自WWDC21:Understand and eliminate hangs from your app)和
Diagnose Power and Performance regressions in your app想了解更多WWDC2021内容的小伙伴,可以阅读我以下文章,欢迎多多交流和指正
理解main runloop
用户的交互均在主线程的Runloop发生。当用户和APP交互,主线程会接受到这个事件,接下来处理这个事件,然后更新UI。
如果处理事件耗费的很长时间,就从用户交互到UI更新之间会发生延时(delay)。
Hang通常由什么引起?
-
主线程任务忙(Busy)
例如:过渡加载资源。当前页面中只需要展示前4个图片,但是却一次性加载了所有的图片。
例如:执行了与主线程不相关的任务。
再比如了使用次优的API。像绘制图片圆角有两种方法:
-
方法一:
-
方法二:
比较这两种方法,法一是CPU密集型操作,会消耗大量内存。法二使用GPU进行绘制,更快更及时。
-
-
主线程阻塞(Blocked)
可能导致主线程阻塞的操作,例如:
-
同步请求网络,并等待数据返回
-
文件IO等访问系统资源的行为
-
数据库操作
-
锁
-
如何诊断Hang
-
使用Instruments,排查线下的问题
-
Time Profile
-
-
使用MetricKit,检测线上的情况
如果治理Hang?
核心目标:减轻主线程的工作
-
优化必需在主线程中执行的任务
-
使用缓存
例如:由其他线程负责保存和更新缓存,主线程只负责读
-
使用Notification
在主线程中发送通知,其他线程接受通知并异步处理数据
-
-
移除主线程不必要的任务
通常来说,为UI提供关键信息的任务,应该在主线程执行。此外,所有的View和View Controller必须在主线程创建、修改和销毁。
而计算任务可以在其他线程执行,然后在主线程同步UI。一些不重要的维护、非时间敏感的任务应该在其他线程异步执行。
例如:网络请求
-
使用GCD异步处理任务
-
Instruments工具包含了非常丰富的数据,可以自由选择查看各机型、各指标类目的具体性能数据,同样也正因为其展示的数据太过庞杂,可能让开发者不清楚该从如何入手去进行优化。
Xcode 13中Instruments中新增了Regressions模块,它会突出需要优先处理的性能问题,来简化工作流。
二:Regressions
理解Instrument中的Regression
当一个APP相对与近期的版本,在性能或电量方面发生劣化,就称为回归(Regression)。
比如在上线一个新版本后,APP启动时间增加。
最新版本的启动时间,会与近期几个版本的启动时间的平均值进行比较,如果最新版本的启动时间更长,就会标记为回归。
Regression左侧栏汇总了哪些指标被回归,以及相较上几个版本劣化了多少。
-
Disk Writes
磁盘和内存还有CPU一样都是受限制的资源,不检查磁盘写入会损耗和伤害底层设备,同时还可能造成Hang(用户操作超过250ms未响应记作一个Hang)和UI卡顿,甚至缩短电池寿命。
- Insights
Organzier新增了一个叫做Insights区域的区域,来提供一些性能优化建议
-
File activities
Instruments中的File activities也可以用来debug储存相关的问题。
相关资料
Diagnose power and performance regressions in your app
Improving battery life and performance
Modernizing Grand Central Dispatch