如何提高iOS应用的性能
基础
在开始建议之前,最好先定义并阐明本文之外的基本概念,这是主要主题 。
您可能已经知道,主线程不应用于繁重的操作,而应主要用于:
- 接受用户输入/交互;
- 显示结果并更新UI。
当主线程必须处理太多操作时,最常见的后果是丢帧现象,这是很普遍的现象,当我们不能保证60 fps(或每16.67毫秒一次)时,就会发生这种情况。
如何调试和识别精确丢失的帧?
有时,很容易发现它们,因为最关键的问题是不响应 ,而其他时候则不是,我们需要更准确的信息来跟踪它们。 例如,使用CADisplayLink (以非常快速的方式直接通过代码跟踪它们)或使用TimeProfiler以更准确的方式进行跟踪 。
要使用CADisplayLink,您可以简单地使用此类:
现在您知道您的帧下降了,该怎么办? 您可以采取一些措施,在本文中,我建议一些措施:
- 减少视图和透明视图的数量
- 最小化在连续调用的函数中完成的工作量
- 解码JPEG图像
- 屏幕外渲染
让我们一一讨论。
1.减少视图和透明视图的数量
为了提高应用程序的性能,要做的第一件事是(尽可能):
- 减少视图数量;
- 避免透明。
解决第二点很简单:
label.layer.opacity = 1.0
label.backgroundColor = .white
为了轻松发现透明胶片的这种重叠,我们可以依靠一个非常方便的工具:调试->视图调试->渲染-> 颜色混合层 。
该工具使我们可以轻松地发现视图重叠,如以下示例所示:
2.最小化连续调用函数中完成的工作量
似乎很明显,但是像cellForItemAt indexPath或scrollViewDidScroll之类的函数必须非常快,因为它们是连续调用的。
始终确保使用最轻巧的配置方法来拥有“最哑”的视图/单元。 (例如,不涉及布局约束,对象分配等)
3.解码JPEG图像
当我们处理掉帧问题时,“通常的嫌疑人”之一就是图像解码。 通常,此操作是在主线程下通过imageViews完成的。 但这有时会导致我们的应用程序持续减速,尤其是在图像很大时。
为了减轻该问题,一种解决方案是将解码工作移至后台队列 。 这样,操作将不会像UIImageView所采用的常规解码那样高效,但是mainThread将是免费的。 下面让我们看一下卢克·帕罕(Luke Parham)的“ Catstagram”项目中的一些摘录:
在后台解码图像 :
可以在以下类中使用:
从那里,您可以使用“ AsyncImageView”而不是经典的“ UIImageView”来在后台线程而不是主线程中解码图像。
为什么我们使用DispatchQueue.main.sync {}?
由于内存警告是在主线程上处理的,而我们正在处理一个后台线程,因此,如果我们不同步,则在使用过多内存的情况下,很有可能发生意外行为,例如崩溃,这是很大的风险!
如果要测试并查看两种方法之间的区别,请使用此游乐场。
另一个解决方案(减少教学方法)是仅使用此库:https://github.com/rs/SDWebImage
4.屏幕外渲染
当我们不得不处理UI元素的特定属性时,由于在显示它们之前我们需要准备这些元素,因此我们可能会遇到一些屏幕外渲染问题。 换句话说,这意味着大量使用CPU和GPU。
我们如何发现这个问题?
和以前一样,还有另一个非常方便的工具:调试->视图调试->渲染-> 彩色屏幕外渲染的黄色 。
使用此仪器,我们可以立即发现这些元素,因为它们以黄色或红色突出显示,具体取决于它们的“沉重”程度。
一个非常典型的示例是关于cornerRadius属性的使用。 如果您的应用中包含以下内容:
imageView.layer.cornerRadius = avatarImageHeight / 2.0
您可以考虑改用UIBezierPath ,它可以解决特定问题的屏幕外渲染问题:
简而言之,尝试:
- 避免使用CornerRadius属性;
- 除非您真的知道它会有所帮助,否则应避免使用ShouldRasterize ;
- 使用。 四舍五入 ()值,因为它更易于计算。
- 请记住, 阴影也会导致屏幕外渲染。
其他建议
要记住的其他一般建议是:
- 文本度量( boudingRectWithSize )可能非常繁重。 除非非常需要,否则请尽量避免使用它们。
- 始终检查您的层次结构布局,尤其是在使用自动布局并且必须支持较旧的设备时。 (您可能对此UIKonf18演讲感兴趣:“通过GPU优化提高滚动性能”)
- 只要有可能将工作放在后台队列中,那就去做吧! 但是请注意内存警告。
结论
希望这些技巧对您的项目和日常开发工作有所帮助! 随时分享您的想法,并在Twitter上关注/询问我所需的一切!
额外资源
- iOS和macOS性能调优
- Catstagram(带有实际示例的项目)