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의 파싱 시간 0, Segue 해결 시간 0을 구현하고 있습니다. 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 개발자 — UIKit 문서 — SimpleMemo의 UI 구축에 채택한 프레임워크의 공식 레퍼런스
- Apple 개발자 — SwiftUI 문서 — 비교 검토한 선언적 UI 프레임워크. 성능 측정 대상
- Apple 개발자 — os_signpost / OSSignposter — Time-to-Text 측정에 사용한 Instruments 연동의 성능 측정 API
- WWDC 2023 — Analyze hangs with Instruments — UI 응답 최적화를 참고한 WWDC 세션