doggraphs

1 개의 포스트

Datadog의 데이터 시각화를 iOS에 구현한 방법: 성능 최적화에 집중하며 (새 탭에서 열림)

Datadog은 복잡한 데이터 시각화를 iOS 모바일 앱에 네이티브로 구현하기 위해 자체 SwiftUI 기반 그래프 라이브러리인 'DogGraphs'를 개발했습니다. iOS 14 호환성을 유지해야 하는 제약 속에서 성능 병목을 해결하기 위해 SwiftUI의 렌더링 파이프라인과 디핑(Diffing) 메커니즘을 심도 있게 분석하고 최적화했습니다. 그 결과, 다양한 제품군에서 빠르고 유연하게 동작하며 컴파일 타임에 타입 안정성까지 보장하는 선언형 그래프 프레임워크를 구축할 수 있었습니다. ### DogGraphs 개발 배경과 도전 과제 * **자체 라이브러리 필요성**: 개발 당시 Swift Charts 같은 공식 라이브러리가 없었으며, Datadog 특유의 복잡한 데이터 시각화 요구사항을 충족하기 위해 직접 개발을 결정했습니다. * **하위 호환성 제약**: iOS 14를 지원해야 했기에 성능 최적화에 유리한 최신 `Canvas` API를 사용할 수 없었고, 표준 SwiftUI 뷰 계층 구조만으로 고성능을 구현해야 했습니다. * **선언형 API 설계**: Swift의 Result Builder를 활용해 SwiftUI와 유사한 구문으로 복잡한 그래프를 정의할 수 있게 했으며, 서로 다른 유형의 그래프를 잘못 쌓는 등의 실수를 컴파일 타임에 방지하도록 설계했습니다. ### 성능 분석 및 프로파일링 도구 활용 * **_printChanges() 활용**: 뷰의 `body` 내에서 이 비공개 API를 호출하여 어떤 상태 변화가 불필요한 재렌더링을 유발하는지 로그로 확인하고 디버깅했습니다. * **Xcode Instruments**: 'SwiftUI View body evaluations'를 통해 뷰의 바디가 평가되는 횟수와 평균 소요 시간을 측정했으며, 'Time profiler'로 실행 시간이 긴 함수를 찾아 최적화했습니다. * **주요 측정 시나리오**: 초기 그래프 렌더링 시점, 툴팁 선택이나 레이어 토글 같은 상호작용 발생 시, 기기 회전 및 다크/라이트 모드 전환 시의 성능을 집중적으로 점검했습니다. ### SwiftUI 핵심 개념과 디핑(Diffing) 메커니즘 * **렌더링 원리 이해**: SwiftUI의 성능 최적화를 위해 Identity(정체성), Lifetime(생명주기), Dependencies(의존성)라는 세 가지 핵심 개념을 기반으로 뷰 업데이트 방식을 분석했습니다. * **비트 단위 비교**: SwiftUI는 뷰의 필드를 비트 단위로 비교(memcmp)하여 이전 값과 차이가 없으면 `body`를 다시 계산하지 않고 건너跳는 최적화 방식을 사용합니다. * **의존성 관리**: 불필요한 의존성 전파를 막고 뷰 구조를 효율적으로 설계함으로써, 데이터 변경 시 영향을 받는 뷰만 정확히 다시 그려지도록 유도했습니다. ### 실용적인 권장 사항 복잡한 SwiftUI 애플리케이션의 성능을 높이려면 단순히 최신 기능을 사용하는 것에 그치지 말고, **뷰의 정체성(Identity)과 의존성 관계를 명확히 정의**해야 합니다. 특히 대규모 데이터를 다루는 시각화 도구에서는 SwiftUI의 내부 디핑 엔진이 효율적으로 작동할 수 있도록 뷰 모델과 프로퍼티 구조를 최적화하고, Instruments를 통해 렌더링 비용을 주기적으로 측정하는 과정이 필수적입니다.