什么是Hang?
试想这样的场景:当用户在你的APP中进行交互时,APP却没有及时的响应用户的操作。
这种体验可以被描述为延时、慢、卡顿,在Apple开发中,我们称这种无响应的表现为Hang。
(温馨提示:本片内容来源自WWDC21:Understand and eliminate hangs from 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异步处理任务
相关资料
Diagnose power and performance regressions in your app