SwiftUI 성능 프로파일링 with Instruments (실용 가이드)

발행: (2026년 1월 16일 오후 01:10 GMT+9)
9 min read
원문: Dev.to

Source: Dev.to

프로파일링을 하지 않으면, 추측하게 됩니다.
SwiftUI에서 추측은 무작위 .id() 해킹, 불필요한 EquatableView, 깨진 애니메이션, 알 수 없는 끊김, 그리고 시기상조의 마이크로 최적화로 이어집니다.

이 실용적이고 불필요한 얘기가 없는 가이드는 Instruments를 사용해 SwiftUI 앱을 프로파일링하는 방법을 보여줍니다:

  • 어디를 살펴봐야 하는지
  • 무엇이 중요한지
  • 무시해야 할 것
  • 결과를 해석하는 방법
  • 실제 문제를 해결하는 방법

이 가이드는 “느려 보인다” 에서 “왜 그런지 알겠다” 로 이끌어 줍니다.

🧠 핵심 원칙

먼저 측정하고, 그 다음 최적화한다.

전형적인 SwiftUI 성능 문제:

  • 레이아웃 스러싱
  • 과도한 body 재계산
  • 메인 스레드 차단
  • 메모리 churn
  • 뷰 아이덴티티 오용

Instruments가 이 모든 문제를 밝혀줍니다.

🧰 실제로 필요한 4가지 Instruments

나머지는 무시하세요. 다음부터 시작합니다:

  • Time Profiler
  • SwiftUI
  • Allocations
  • Leaks

이 네 가지가 SwiftUI 문제의 약 95 %를 커버합니다.

⏱️ 1. Time Profiler — 실제 병목 찾기

열기 방법: Xcode → Product → Profile → Time Profiler

확인할 항목

  • 메인 스레드에서 오래 걸리는 블록
  • 동일한 함수에 대한 반복 호출
  • 무거운 JSON 또는 이미지 디코딩
  • 레이아웃 루프

주의할 점

  • body가 과도하게 호출되는 경우
  • ViewGraph 업데이트
  • 비용이 많이 드는 모디파이어
  • .task 내 동기 작업

❌ 흔히 보이는 Time Profiler 패턴

body 안에서 무거운 작업

var body: some View {
    let data = heavyComputation()

}

수정 방법

@State private var data: Data

.task {
    data = await heavyComputation()
}

동기 디코딩

let image = UIImage(data: data)

수정 – 메인 스레드가 아닌 곳에서 디코딩 (예: 백그라운드 큐 또는 async API 사용).

🧬 2. SwiftUI Instrument — 뷰 업데이트 추적

활성화: Instruments → SwiftUI

다음과 같은 정보를 확인할 수 있습니다:

  • 어떤 뷰가 다시 렌더링되는지
  • 얼마나 자주 렌더링되는지
  • 왜 업데이트되는지

레드 플래그

  • 아무 변화도 없는데 뷰가 업데이트되는 경우
  • 큰 서브트리가 무효화되는 경우
  • 아이덴티티가 리셋되는 경우
  • 예상치 못한 애니메이션

🧠 SwiftUI Instrument에서의 레드 플래그

  • 부모 뷰 업데이트가 전체 화면 재그리기를 일으킴
  • 작은 상태 변화가 전체 리스트를 무효화함
  • 레이아웃 패스가 반복됨
  • 뷰가 업데이트되지 않고 재생성됨

이는 보통 아이덴티티 문제, 잘못된 상태 위치 지정, 혹은 환경 사용 오류를 나타냅니다.

🧪 3. Allocations — Memory Churn

Open: Instruments → Allocations

Look for

  • 빠른 객체 생성 급증 (예: 스크롤 시)
  • 반복적인 ViewModel 생성
  • 이미지 churn, 작업 churn

이러한 패턴은 메모리 누수, 과다 할당, 그리고 성능 저하 요인을 드러냅니다.

❌ Classic Allocation Problems

Creating objects in body

var body: some View {
    let formatter = DateFormatter()

}

Fix

private let formatter = DateFormatter()

or inject the formatter.

Recreating ViewModels

SomeView(viewModel: ViewModel())

Fix

@StateObject private var vm = ViewModel()

🧯 4. Leaks — 메모리 해제 확인

Open: Instruments → Leaks

앱을 탐색하면서(뷰를 푸시/팝하고, 기능을 열고/닫고, 탭을 전환하는 등) 절대 해제되지 않는 객체를 주시하세요—보통 ViewModels, 서비스, 혹은 컨테이너가 해당됩니다. 만약 deinit되지 않으면 메모리 누수가 발생한 것입니다.

🧭 5. 화면 프로파일링 방법 (단계별)

  1. Instruments를 열고 Time Profiler + SwiftUI를 선택합니다.
  2. 실제 기기에서 문제 화면으로 이동합니다 (시뮬레이터에서는 절대 하지 마세요).
  3. 상호작용: 스크롤, 탭, 애니메이션, 데이터 로드.
  4. 기록을 중지합니다.
  5. 검사: 메인 스레드 활동, SwiftUI 업데이트, 할당.

🧠 6. SwiftUI 재렌더링 해석

스스로에게 물어보세요:

  • 어떤 상태가 변경되었나요?
  • 왜 이 뷰가 무효화되었나요?
  • 정체성이 변경되었나요?
  • 환경이 원인인가요?
  • 부모가 자식을 무효화하고 있나요?

답을 찾지 못한다면, 아키텍처를 리팩터링해야 할 가능성이 높습니다.

🧬 7. 레이아웃 스래싱 감지

증상

  • 스크롤 시 높은 CPU 사용
  • 반복되는 레이아웃 패스
  • 끊기는 애니메이션

Instruments는 레이아웃 함수(예: LayoutComputer)에 대한 반복 호출을 표시합니다.

해결 방법

  • 중첩된 스택 감소
  • GeometryReader 남용 피하기
  • 프리퍼런스 루프 제거
  • 뷰 계층 구조 평탄화

🧪 8. 애니메이션 프로파일링

Use Core Animation and Time Profiler to look for:

  • 프레임 손실
  • 애니메이션 중 레이아웃 작업
  • 전환 블록 내 무거운 수정자

Common fixes

  • 작업을 애니메이션 블록 밖으로 이동
  • 레이아웃을 변경하는 애니메이션을 피함
  • 값을 미리 계산

🧠 9. 실제 환경 프로파일링 체크리스트

다음 시나리오를 프로파일링하세요:

  • 콜드 런치
  • 긴 리스트 스크롤링
  • 네비게이션 푸시/팝
  • 탭 전환
  • 딥링크 진입
  • 백그라운드 → 포그라운드 전환
  • 화면 회전

이러한 상황이 대부분의 성능 문제를 드러냅니다.

❌ 10. 일반적인 안티‑패턴

  • 디버그 빌드에서만 프로파일링하기
  • Instruments 경고 무시하기
  • 근거 없이 최적화하기
  • SwiftUI를 무조건 비난하기
  • 무작위 수식어를 사용해 “jank”를 고치려 하기
  • 프로파일링 없이 배포하기

Performance is not optional. (성능은 선택 사항이 아닙니다.)

🧠 멘탈 모델

User Action
 → State Change
   → View Invalidation
     → Layout
       → Render
         → GPU

Instruments는 어느 단계가 깨졌는지 보여줍니다.

🚀 최종 생각

Instruments는 “느리게 느껴진다”“이 함수가 메인 스레드를 32 ms 동안 차단합니다.” 로 바꿔줍니다.

정기적으로 사용하면 다음과 같은 효과가 있습니다:

  • 더 나은 아키텍처
  • 높은 코드 품질
  • 버그 감소
  • SwiftUI 앱에 대한 더 큰 신뢰
Back to Blog

관련 글

더 보기 »

안녕 개발자: 2026년 1월

우리는 2026년에 바로 본격적으로 시작합니다. 이번 호에서는: 쿠퍼티노에서 진행되는 특별한 SwiftUI 활동. Liquid Glass에 대해 우리와 연결할 수 있는 방법이 더 많아졌습니다. 스냅한 vi...

Python: Tprof, 타깃팅 프로파일러

Python: tprof, 타깃 프로파일러 소개. 프로파일러는 전체 프로그램의 성능을 측정하여 대부분의 시간이 어디에 소비되는지 식별합니다. 하지만 일단 당신이…