SwiftUI视图卡顿冻结原因排查求助
SwiftUI视图卡顿冻结原因排查求助
大家好,我最近碰到了一个棘手的SwiftUI视图卡顿冻结问题,试过各种调试还是没找到根因,想请各位大佬帮忙分析下。
先交代下环境:
- Xcode版本:16.2
- 测试设备:iOS 18.5 物理真机
不过这个冻结问题并非特定版本独有,我在好几个版本里都遇到了,还专门做了个极简测试项目来复现,操作步骤很明确:
- 运行测试App
- 打开VoiceOver功能
- 点击一次「Header」文本,让VoiceOver完成朗读
- 关闭VoiceOver
- 快速上下滚动页面
我用Time Profiler分析了主线程的耗时占比,发现这些调用栈的耗时特别突出:
- 19.11 s(85.1%):
closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) - 13.05 s(58.1%):
ViewGraph.updateOutputs(async:) - 7.97 s(35.5%):
AG::Graph::UpdateStack::update() - 5.76 s(25.6%):
LayoutScrollableTransform.updateValue() - 1.73 s(7.7%):
specialized NativeDictionary.setValue(_:forKey:isUnique:) - 579.00 ms(2.6%):
0x100a8c908 - 311.00 ms(1.4%):
__thread_stack_pcs
冻结期间,内存占用以每秒约0.6MB的速度持续上涨。另外我还发现几个能规避冻结的操作,但这些调整在我的实际项目里都不可行——因为这些元素都是业务必须的:
- 把LazyVStack替换成VStack
- 移除Section内部的VStack
- 去掉Section的
header:参数 - 缩小ForEach的遍历范围
- 把
Text(verbatim: "Bottom Text")移到LazyVStack外面
所以想请教大家:到底是什么引发了这个卡顿?是不是我在SwiftUI的使用方式上有不符合设计意图的地方?
下面是测试项目的完整代码:
ContentView.swift
import SwiftUI struct ContentView: View { var body: some View { VStack { VStack(alignment: .leading) { Image(systemName: "pencil.circle.fill") Text("Title") Text("Label") } ScrollView { LazyVStack { Section { VStack { ForEach(0..<70) { _ in Text(verbatim: "A") } } } header: { Text(verbatim: "Header") } Text(verbatim: "Bottom Text") } } } } }
AppDelegate.swift
import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let window = UIWindow(frame: UIScreen.main.bounds) window.rootViewController = UINavigationController(rootViewController: MainViewController()) window.makeKeyAndVisible() self.window = window return true } }
MainViewController.swift
import UIKit import SwiftUI final class MainViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let swiftUIView = ContentView() let hostingController = UIHostingController(rootView: swiftUIView) addChild(hostingController) hostingController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingController.view) NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) hostingController.didMove(toParent: self) view.backgroundColor = .white } }
内容来源于stack exchange
相关产品推荐
相关产品推荐

