반응형

앱 시작 속도 개선(App Launch Optimization)

 

1. 들어가며

앱의 첫인상은 Launch Time(앱 시작 속도)입니다.

사용자는 앱이 1~2초 안에 뜨면 “빠르다”고 느끼고, 3초가 넘으면 “느리다”고 인지합니다.

특히 다음 환경에서는 시작 속도가 더 중요합니다.

  • 광고 기반 앱
  • SNS/커뮤니티 앱
  • 인증/보안 앱(OTP, 카드 등)
  • 휘발성 기능 중심 앱(메모, 할 일, 카메라)

이 문서는 iOS 실무에서 앱 시작 시간을 30~70% 단축할 수 있는 최적화 기술을 정리한 가이드입니다.

 

2. 앱 시작 속도의 구성 요소


앱 시작은 크게 3단계로 나뉩니다.

2.1 Pre-main (dyld 단계)

  • 동적 라이브러리 로딩
  • 의존 프레임워크 로딩
  • Objective‑C 런타임 처리

2.2 Main 이후 AppDelegate 초기화

  • Scene 초기화
  • Firebase/Analytics 초기화
  • CoreData 초기화

2.3 첫 화면 렌더링

  • ViewController 생성
  • 네트워크 호출 여부
  • 무거운 UI 초기화 여부

각 단계의 시간을 줄이는 것이 핵심입니다.

 

3. Pre-main 최적화 — 가장 강력한 성능 개선 구간


3.1 Dynamic Framework 개수 줄이기

dyld가 가장 많은 시간을 차지하는 부분.

나쁜 예:

  • Firebase 분석, Crashlytics, RemoteConfig, Messaging 등 모두 포함
  • 20개 이상의 외부 SDK 사용

해결:

  • 사용하지 않는 SDK 제거
  • SPM 사용 시 binary target 최소화

3.2 Objective‑C 런타임 코드 최소화

Objective‑C 카테고리 확장, Swizzling 등은 pre-main 비용 증가 원인.

개선:

  • Swift 기반 코드로 대체
  • swizzling 최소화

 

4. AppDelegate / SceneDelegate 최적화


4.1 초기화 작업 최소화

앱 시작 시 아래 코드는 절대 넣지 말 것:

  • 대규모 API 호출
  • CoreData 전체 fetch
  • AI/ML 모델 로딩
  • 이미지 캐시 미리 생성
  • 무거운 파일 읽기

원칙:

“앱 시작 시에는 가장 필요한 것만 남기고 모두 뒤로 미뤄라.”


4.2 Lazy Initialization 활용

lazy var analytics = AnalyticsManager()

필요할 때 불러오면 실제 시작 속도는 빨라짐.


4.3 Heavy Object는 백그라운드에서 로드

DispatchQueue.global().async {
    HeavyManager.shared.prepare()
}

 

5. 첫 화면(Rendering) 최적화


5.1 RootViewController는 가벼워야 한다

피해야 할 것:

  • 복잡한 layout 구성
  • 이미지 다수 로딩
  • Massive ViewModel

추천:

  • Skeleton UI
  • Placeholder UI
  • 핵심 콘텐츠는 background preload


5.2 SwiftUI 앱의 경우

초기 View에서 StateObject 생성 남발 금지.

@StateObject var vm = HeavyViewModel()   // ❌

→ 메모리·CPU spike 발생

해결:

초기에는 lightweight ViewModel 사용


5.3 Launch Screen은 절대 애니메이션 금지

iOS 정책상 불가능하기도 하지만

LaunchScreen.storyboard에서 너무 많은 제약 조건은 성능 저하 원인.

 

6. 네트워크 호출 최적화


6.1 앱 시작하자마자 API 2~5개 호출 → 최악

나쁜 예:

fetchConfig()
fetchUserProfile()
fetchNotice()
fetchAd()
fetchRemoteSettings()

해결:

  • Config → 캐시 후 필요시 최신화
  • Notice → 앱 뒤에서 가져오기
  • UserProfile → Local Cache 우선
  • Ad → 비동기 로드


6.2 URLSession 초기 설정 최적화

let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 10

불필요한 timeout 증가 방지.

 

7. 이미지 로딩 최적화


7.1 반드시 캐싱 라이브러리 사용

  • Kingfisher
  • Nuke
  • SDWebImage

메모리 캐시 미사용 시 불필요한 다운로드 반복.


7.2 Resize는 백그라운드에서 처리

큰 이미지를 UI 스레드에서 resize하면 프레임 드랍 발생.

 

8. Static 초기화 주의


아래 코드는 앱 시작 성능을 심각하게 떨어뜨릴 수 있음.

static let shared = HeavyObject()

→ 앱 시작 시 즉시 메모리 잡힘

권장:

static var shared: HeavyObject = {
    return HeavyObject()
}()

또는 lazy 사용.

 

9. Instruments로 LaunchTime 측정


9.1 Time Profiler

초기 CPU Spike 확인

9.2 System Trace

dyld 로딩 시간 확인

9.3 Logging

os_signpost 활용하여 초기화 타이밍 체크

 

10. 체크리스트

  •  Dynamic Framework 최소화
  •  초기 큰 객체 생성 지연
  •  API 호출 최소화
  •  Heavy ViewModel 생성 금지
  •  Skeleton UI 도입
  •  RootView를 단순화
  •  이미지 로딩 최적화
  •  Static 초기화 재검토
  •  Instruments로 측정

 

11. 결론

앱 시작 속도는 “앱 품질”의 상징이며 이탈률에 직접적인 영향을 미칩니다.
모든 기능을 앱 시작 시 불러올 필요는 없으며,
필요한 순간에 로드하는 지연 전략(Lazy Loading)이 핵심입니다.

반응형
Posted by 까칠코더
,