AnyView 对 SwiftUI 性能的影响

💡 原文中文,约3100字,阅读约需8分钟。
📝

内容提要

AnyView是一种类型擦除的视图,对于SwiftUI容器中的异构视图非常方便。然而,使用AnyView可能会导致功能损失。通过对比使用泛型和使用AnyView的修正完成,进行了一些测量。结果显示,在阅读数据时,使用AnyView会导致功能退化约10%至16.5%。因此,在异构视图的可滚动列表中,最好为容器中的不同视图使用具体类型,而不是使用AnyView。

🔎

延伸解读

性能退化的具体表现

文章通过对比测试发现,在滚动阅读数据时,使用AnyView会导致平均FPS从59降至55,性能退化约10%;而在滚动同时更新视图的场景下,FPS进一步降至50以下,退化约16.5%。这些数据表明,AnyView对性能的影响在动态更新时更为显著,且会带来更多可见的卡顿。

AnyView为何影响性能

SwiftUI依赖视图的身份和结构来高效更新界面。AnyView作为类型擦除包装,隐藏了具体类型,导致SwiftUI无法识别视图标识,每次更新时都可能重新创建整个视图。文章引用WWDC内容指出,列表需要提前知道所有标识符,而AnyView使行数无法确定,必须提前创建所有视图,从而影响性能。

适用场景与限制

文章强调,AnyView并非总是不好。在菜单等异构元素列表且点击后导航目标不同的场景中,测试未发现性能差异。此外,使用if-else语句与AnyView在测试中也没有明显性能差异,因为两者都会导致视图标识丢失。因此,是否使用AnyView需结合具体实现和数据更新频率来判断。

优化建议

基于测试结果,文章建议在异构视图的可滚动列表中,尽量为不同视图使用具体类型,而不是AnyView。虽然这可能听起来更复杂,但可以通过简化泛型处理来降低复杂度。避免在ForEach中使用AnyView或条件检查,以确保SwiftUI能高效管理视图标识和结构。

❓

Q&A

AnyView是什么,它在SwiftUI中有什么作用?

AnyView是一种类型擦除的视图,适用于SwiftUI容器中的异构视图,能够简化代码而无需指定每个视图的详细类型。

使用AnyView会对SwiftUI的性能产生什么影响?

使用AnyView可能导致功能损失,性能退化约10%至16.5%,并且在更新视图时可能出现更多的卡顿。

在什么情况下使用AnyView对性能影响不大?

在某些情况下,例如菜单视图中,使用AnyView对性能影响不大。

Apple对在ForEach中使用AnyView有什么建议?

Apple建议在ForEach中避免使用AnyView,以防止性能问题。

在没有AnyView的情况下,SwiftUI的性能表现如何?

在没有AnyView的情况下,平均FPS约为59帧,滚动流畅且响应迅速。

使用AnyView时,FPS会降到多少?

使用AnyView时,平均FPS降至55帧,更新视图时可能降至50以下。

🏷️

标签

➡️

继续阅读