UIKit vs SwiftUI:为了启动速度选择UIKit的理由
本页面由日语原文机器翻译而成。 阅读日语原文
1。 为什么2026年是UIKit
Apple在每年的WWDC上强调了SwiftUI的进化,宣言性UI的便利性已经毋庸置疑了。
但是,这个软件有不能让步的要求。 那就是将Time-to-Text(从启动到可以输入文本的时间)降到500ms以下。
在SwiftUI中,@StateObject的初始化、body的重新评估、.onAppear的定时控制等,存在声明性UI框架固有的开销。 这些在一般的应用程序中是可以忽略的程度,但在追求以毫秒为单位的优化的场景中是不能忽视的。
另一方面,从UIKit的viewDidAppear呼叫becomeFirstResponder()的路径是决定论上高速。 ViewController的生命周期很明确,可以准确地控制键盘何时显示。
2。 完全排除Storyboard的理由
仅仅选择UIKit是不够的。 Storyboard也有影响启动性能的开销。
- XML解析成本:Storyboard内部是XML文件,启动时需要解析
- Segue解决成本:为了画面转换的Segue设置解决需要时间
- 不必要的复杂性:简单的备忘录应用程序Storyboard的视觉设计工具过度
代替,采用了用SceneDelegate直接生成ViewController的方式。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
PerformanceLogger.shared.signpostBegin(name: "SceneConnect")
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let composeVC = ComposeViewController()
let navController = UINavigationController(rootViewController: composeVC)
window.rootViewController = navController
window.makeKeyAndVisible()
PerformanceLogger.shared.signpostEnd(name: "SceneConnect")
}
通过这种方法,实现了Storyboard的零解析时间、Segue解决时间零。 通过从SceneDelegate直接生成ComposeViewController,从启动路径中完全排除了不必要的处理。
3. viewDidAppear的1行全部完成
UIKit的最大优势是明确定义了ViewController的生命周期。 viewDidAppear(_:)被调用时,视图完全显示在屏幕上。 通过在这个确定的时机调用becomeFirstResponder(),可以最大限度地减少键盘显示的延迟。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
activateTextInput()
}
private func activateTextInput() {
textView.becomeFirstResponder()
PerformanceLogger.shared.endTimeToText()
}
通过os_signpost以纳秒精度进行测量。 PerformanceLogger.shared.endTimeToText()记录了Signpost的结束事件,使Instruments的详细分析成为可能。
4。 性能测量的机制
不是“快”的感觉判断,而是根据定量数据进行设计判断。
- PerformanceLogger:包装
os_signpost的定制记录器。 测量启动、发送、UI更新的各个阶段 - Instruments合作:通过Xcode的os_signpost Instrument可以进行纳米秒精度的追踪
- 主要指标:Time-to-Text(启动→可输入)、Send-to-Reset(发送按钮→UI初始化)
- 持续监控:在开发中的所有构建中进行性能测量,即时检测回归
性能是功能。 即使用户不明确要求“速度”,慢的应用程序也会不自觉地使用。 正因如此,持续用数值管理性能很重要。
5。 有使用SwiftUI的场景吗
UIKit并不是一选。 在应用内,也有适合SwiftUI的场景。
- 设置画面:在不影响启动速度的非关键画面中,SwiftUI的声明性UI可以提高生产力
- 关键路径的定义:启动→输入备忘录→发送的核心流程由UIKit维持
- 混合的复杂性:UIKit和SwiftUI混合时,需要注意UIHostingController的管理和数据流的一致性
- 现在的判断:备忘录应用程序的UI很简单,用全屏UIKit统一的话可以保持代码基础的一致性
如果未来SwiftUI的性能进一步改善的话,还有重新评价的余地,但关键路径的UIKit是暂时维持的方针。
常见问题
@StateObject的初始化和body的重新评价部分会增加处理。 在以最快为目标的这个开发中,选择了可以精细控制生命周期的UIKit(两者不是在同一条件下测量比较的结果)。os_signpost记录区间,用Instruments进行分析。参考文献
- Apple Developer — UIKit Documentation — SimpleMemo的UI构建采用的框架的官方参考
- Apple Developer — SwiftUI Documentation — 比较探讨的宣言性UI框架。 性能测量对象
- Apple Developer — os_signpost / OSSignposter — 用于Time-to-Text测量的Instruments配合的性能测量API
- WWDC 2023 — Analyze hangs with Instruments — UI响应优化的参考WWDC会议