이전에 FlexLayout과 PinLayout에 대해 간단히 정리해보았었는데, 이번 글에서는 '왜 더 빠른지'에 대해 초점을 맞춰 글을 작성해보고자 합니다.
성능의 핵심인 레이아웃 엔진의 수학적 차이와 그 대안인 FlexLayout, PinLayout에 대해 깊게 파헤쳐 보겠습니다.
1. Auto Layout의 심장: Cassowary 알고리즘의 한계
Apple이 채택한 Auto Layout은 Cassowary(카소와리)라는 선형 방정식(Linear Equation)를 기반으로 합니다.
| 수학적 메커니즘: "방정식을 푸는 수학자"
Auto Layout에 제약을 추가하는 것은 시스템에 다음과 같은 연립 부등식을 던져주는 것과 같습니다.
ViewA.leading = ViewB.trailing + 10 ViewA.width = ViewB.width * 2
- 동작 원리: 시스템은 이 수많은 방정식을 하나의 거대한 행렬(Matrix)로 만듭니다. 그리고 심플렉스(Simplex) 알고리즘을 사용해 모든 조건을 만족하는 최적의 해를 찾을 때까지 반복 연산을 수행합니다.
- 성능 저하의 이유 (Global Complexity): 하나의 뷰 크기만 변해도 연쇄 작용으로 인해 전체 행렬을 다시 계산해야 할 수도 있습니다. 뷰 계층이 깊어질수록 계산 복잡도는 $O(n^k)로 치솟으며 CPU에 큰 부담을 줍니다.
2. PinLayout: 결정론적 산술 연산 (Deterministic)
PinLayout의 개발자 Luc Dion은 그의 강연에서 "예측 가능성"을 강조합니다. PinLayout은 수학 문제를 푸는 대신 직접적인 대입을 선택했습니다.
왜 압도적으로 빠른가?
- 산술 연산: "이 방정식의 해를 구해줘"가 아니라 "x에 100을 넣어"라는 명령입니다. (x = 10 + 20 + 70)
- layoutSubviews의 활용: 레이아웃이 결정되어야 하는 최종 시점(layoutSubviews)에 딱 한 번, 순수 산술 연산만 수행하여 frame에 할당합니다.
- 영향 범위의 국한: 특정 뷰의 레이아웃 코드가 실행되어도 다른 뷰의 방정식 시스템에 영향을 주지 않습니다. 연산 비용이 O(n)으로 일정합니다.
3. FlexLayout: Yoga 엔진과 단방향 패스
FlexLayout은 웹의 Flexbox 모델을 iOS로 가져왔으며, 내부적으로 C++로 작성된 Yoga 엔진을 사용합니다.
수학적 메커니즘: "분할 정복(Divide and Conquer)"
- 단방향 패스(One-pass): 부모부터 자식까지 트리를 한 번 훑으며 내려가는 구조입니다.
- 지역적 계산: 전체 화면을 하나의 문제로 보지 않고, 각 컨테이너(부모)가 자식들의 크기만 결정하면 끝납니다.
- 멀티스레딩의 가능성: Auto Layout 엔진은 메인 스레드에 종속적이지만, Yoga는 백그라운드 스레드에서 레이아웃 계산이 가능합니다. 이는 UI 응답성을 극대화하는 핵심 기술입니다.
4. 기술적 디테일 비교 (Summary)
| 항목 | Auto Layout | PinLayout | FlexLayout |
| 알고리즘 | Cassowary (Simplex) | Procedural (직접 산술) | Yoga (Tree Traversal) |
| 수학적 접근 | Optimization (최적해 찾기) | Assignment (값 대입) | Propagation (값 전파) |
| 성능 복잡도 | $O(n^k) (기하급수적) | $O(n) (선형적) | $O(n) (선형적) |
| 유연성 | 매우 높음 (Apple 표준) | 높음 (정교한 제어) | 보통 (Flexbox 규칙 준수) |
5. 결론: 언제 무엇을 쓸 것인가?
우리는 무조건 "Auto Layout은 나쁘다"라고 결론지어서는 안 됩니다.
- Auto Layout: 기기 대응이 복잡하고 일반적인 비즈니스 로직이 중심인 화면에서 생산성이 가장 좋습니다.
- PinLayout: 복잡한 애니메이션, 뷰의 겹침(Overlapping)이 잦거나 극한의 프레임 드랍을 막아야 하는 상황에 적합합니다.
- FlexLayout: 리스트 형태의 복잡한 UI, Code-based UI를 선호하며 가독성과 성능의 밸런스를 잡고 싶을 때 최고의 선택입니다.
결국 성능 최적화의 핵심은 "연산의 범위를 좁히는 것"입니다. 전체 화면을 방정식의 늪에 빠뜨리지 말고, 복잡한 부분부터 Flex와 Pin으로 독립시켜 보세요. 여러분의 앱은 훨씬 더 부드러워질 것입니다.
728x90
'iOS > UIKit' 카테고리의 다른 글
| [UIKit] FlexLayout이란 (0) | 2025.07.31 |
|---|---|
| [UIKit] PinLayout이란 (2) | 2025.07.30 |
| [UIKit] 메모리 관점에서의 CollectionView, PageView, ScrollView의 동작 방식 (2) | 2025.01.29 |
| [iOS-UIKit] Final 키워드를 사용하는 이유 (최적화의 관점) (0) | 2025.01.19 |
| [UIKit] 문자열 보간법의 실행 구조 (feat. UI*.text) (0) | 2025.01.06 |