콘텐츠로 바로가기

Binary Size & Resource Optimization Mechanics

Binary Size 및 자원 Optimization 메커니즘의 정의, 범위, 선행 지식, 학습 주제, 참고 근거를 정리한 CS&E 학습 노드입니다.

목차 보기20

1. Overview

바이너리 크기 및 리소스 최적화 역학(Binary Size & Resource Optimization Mechanics)은 컴파일이 완료된 모바일 앱(APK/AAB, IPA)을 사용자가 다운로드할 때 발생하는 셀룰러 데이터 낭비와 기기 용량 고갈을 막기 위해, 컴파일러 레벨에서 코드를 도려내고 이미지를 픽셀 단위로 압축하는 한계 물리(Physics)를 다룹니다.

서버 개발자가 하드디스크 용량을 크게 신경 쓰지 않는 반면, 모바일 개발자는 앱 용량이 100MB를 넘는 순간 다운로드 전환율(Conversion Rate)이 급락하는 비즈니스 타격을 맞습니다. 학습자는 죽은 코드(Dead Code)를 잘라내는 트리 쉐이킹(Tree Shaking)과 안드로이드의 R8(Proguard) 룰을 분해하고, 여러 해상도의 비트맵(PNG)을 하나의 해상도 무관 벡터 렌즈(SVG/VectorDrawable)로 압축하거나 WebP로 치환하는 에셋(Asset) 최적화 물리를 통제합니다. 또한, AAB(Android App Bundle)와 iOS App Thinning을 통해 사용자의 기기 모델에 꼭 맞는 코드 덩어리(Slice)만 배달되도록 분할 조립(Split)의 역학을 체화합니다.

2. Scope & Boundaries

In-Scope

  • 컴파일 타임 최적화: R8/Proguard (안드로이드), LLVM Bitcode/App Thinning (iOS), Tree Shaking.
  • 리소스 다이어트: 이미지 포맷 변환(WebP), VectorDrawable/SVG, 중복 폰트 제거, Audio 압축.
  • 배포 아키텍처: Android App Bundle (AAB), Play Feature Delivery (On-demand 모듈), iOS On-Demand Resources.
  • 메모리(RAM) 최적화 연계: 거대 비트맵(Bitmap) 렌더링 시 발생하는 Out of Memory (OOM) 억제 방어선.

Out-of-Scope

  • 소스 코드 내부 아키텍처 리팩토링: 클래스를 분리하여 유지보수성을 높이는 코드 레벨 작업 ightarrow ightarrow 09-03. Software Architecture 영역으로 위임.
  • 네트워크 CDN 이미지 리사이징: 서버가 사진을 줄여서 보내는 런타임 백엔드 통신 로직 ightarrow ightarrow 08-03. Application Layer Protocol (HTTP) 영역으로 위임.

Boundaries

  • 모바일 압축 vs 서버 압축 (03-05 vs 13-04-01): 파일 시스템(03-05) 레벨의 zip 텍스트 압축이 디스크 공간을 아끼는 범용적 수학이라면, 13-04-01은 유저의 '아이폰 15'에 '아이폰 12'용 코드가 들어가는 것을 막기 위해 애플리케이션 프레임워크가 아키텍처(arm64) 칩셋별로 바이너리를 가위질(Slicing)해버리는 모바일 생태계 특유의 배포 물리입니다.

3. Counterexample

  • 단일 거대 바이너리 맹신 (Fat Binary Fallacy): x86 에뮬레이터용 라이브러리, 태블릿용 4K 이미지, 한국어/영어/스페인어 문자열을 모두 욱여넣어 1GB짜리 Fat APK를 만드는 무지. 다운로드 버튼을 누른 50%의 유저가 중간에 취소합니다. Android App Bundle(AAB)을 적용하면 구글 플레이 스토어가 유저의 기기를 판별하여, "한국어를 쓰는 ARM64 스마트폰"에 맞는 조각(Slice)만 조립해 30MB 사이즈로 꽂아줍니다.
  • 안일한 이미지 삽입 (Bitmap Hoarding): 앱 디자이너가 준 고해상도 PNG(3MB) 파일 100개를 아무 의심 없이 그대로 assets 폴더에 박아 넣는 행위. PNG를 Vector(XML)나 WebP 형식으로 압축(Shrinking)하지 않으면 바이너리 크기가 터지는 것은 물론, 이 이미지를 메모리에 올릴 때 힙(Heap) 메모리가 100MB씩 치솟아 OOM 크래시가 발생합니다.

4. Prerequisites

  • 컴파일러 물리 (Basic): 소스코드가 링커(Linker)를 통해 바이너리로 묶이는 과정을 알아야 안 쓰는 코드를 잘라내는 트리 쉐이킹을 이해할 수 있습니다. (05-03. Compiler Physics)
  • 컴퓨터 그래픽스 기초 (Recommended): 비트맵(픽셀) 이미지와 벡터(수학 좌표) 이미지의 물리적 렌더링 차이를 알아야 에셋 용량 최적화를 알 수 있습니다. (12-02. Visual Grammar)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 Tree Shaking & Obfuscation R8이나 LLVM이 내가 쓰지도 않는 서드파티 라이브러리의 클래스를 컴파일 타임에 물리적으로 도려내는 가위질을 이해합니다. Primary
2 Asset Compression 기가바이트(GB) 단위의 PNG/JPG 에셋을 WebP나 Vector로 깎아내어 파일 용량의 90%를 물리적으로 증발시킵니다. Industry
3 App Bundles & Thinning 거대한 앱 덩어리를 칩셋별, 해상도별, 언어별로 수십 개로 쪼개어, 각 기기에 맞는 조각만 배달하는 다이내믹 딜리버리를 구축합니다. Industry
4 On-demand Delivery 한 달에 한 번 쓰는 '결제' 모듈을 앱 설치 시엔 빼버리고, 유저가 결제창을 누를 때 런타임에 다운로드받게 스플릿(Split)합니다. Industry

6. Learning Topics

Basic

Core Topic 01: 죽은 코드 제거(Tree Shaking)와 난독화 축소

  • Why to Learn: 10개의 함수가 들어있는 외부 라이브러리에서 딱 1개만 썼을 때, 나머지 9개를 앱 바이너리에 넣고 배포하는 용량 낭비를 컴파일러에게 지시하여 막기 위함입니다.
  • What to Learn: Dead Code Elimination, Tree Shaking, R8(Android), Proguard Rules, LLVM Bitcode Stripping(iOS).
  • How to Learn: 빌드(Build) 과정에서 정적 분석기(Static Analyzer)가 main()에서 시작해 호출되지 않는 모든 클래스와 메서드 그래프를 검은색(도달 불가)으로 칠한 뒤 가차 없이 삭제해 버리는 추적 그래프 물리를 분석합니다.
  • Implement: 리플렉션(Reflection)을 통해 런타임에만 호출되는 숨겨진 클래스가 R8에 의해 실수로 삭제되어 앱이 터지는 현상(ClassNotFoundException)을 재현하고, -keep 룰을 작성하여 방어하는 난독화 제어 테스트 구현.

Core Topic 02: 이미지 리소스 압축과 벡터 변환(WebP, SVG)

  • Why to Learn: 앱 용량의 80%를 차지하는 픽셀 덩어리(PNG)의 사슬을 끊고, 용량이 1/10도 안 되는 벡터나 최신 코덱으로 교체하기 위함입니다.
  • What to Learn: PNG vs WebP, VectorDrawable/SVG, Bitmap Resolution, Lossy vs Lossless Compression.
  • How to Learn: 1000x1000픽셀 PNG(1MB)가 메모리 램(RAM)에 올라갈 때 1000×1000×41000 \times 1000 \times 4 바이트(ARGB) = 4MB 공간을 잡아먹는 계산식을 세우고, 이를 수학적 선과 곡선 좌표로 이루어진 5KB짜리 SVG로 바꿨을 때 무한대로 확대해도 픽셀이 깨지지 않는 벡터 물리를 증명합니다.
  • Implement: 빌드 프로세스(Gradle/Fastlane 플러그인)에 Image Shrinker를 달아, 개발자가 PNG를 폴더에 넣어도 컴파일 타임에 자동으로 80% 압축된 WebP로 강제 컨버팅되도록 빌드 파이프라인 개조.

Core Topic 03: App Bundle (AAB)과 App Thinning 역학

  • Why to Learn: 안드로이드 유저의 기기가 x86 태블릿인지, ARM 폰인지 일일이 알 수 없으므로 스토어 서버가 유저에 맞춰 알아서 앱을 잘라 주게 만들기 위함입니다.
  • What to Learn: Android App Bundle(AAB), APK Splits, iOS App Thinning, ABI(Application Binary Interface) Slicing.
  • How to Learn: 기존 .apk 배포 방식에서는 x86 코어와 ARM 코어용 라이브러리가 모두 합쳐진 통뼈(Fat) 구조였으나, .aab 포맷으로 올리면 구글 서버가 기기에 설치될 때 base.apk + arm64.apk + ko-KR.apk로 실시간 분해(Split)하여 쏘아주는 클라우드 분배망(CDN)을 이해합니다.
  • Implement: Bundletool CLI를 사용해 생성된 .aab 파일에서 특정 가상 기기(예: Pixel 4, xhdpi 해상도)에 딱 맞는 최소 APK 패키지(APKs)만을 물리적으로 추출(Extract)해 용량 절감을 검증하는 쉘 스크립트 작성.

Core Topic 04: 온디맨드(On-demand) 리소스 딜리버리

  • Why to Learn: 500MB짜리 게임 리소스나 AR 카메라 모듈을 초기 설치 용량에 넣으면 유저가 도망가므로, 기능이 필요한 그 찰나의 순간에 부분 다운로드를 치기 위함입니다.
  • What to Learn: Play Feature Delivery, Dynamic Feature Modules (DFM), iOS On-Demand Resources (ODR).
  • How to Learn: 앱의 핵심 엔진(Base) 모듈 10MB만 먼저 설치하여 TTI(Time to Interactive)를 앞당기고, 백그라운드 코루틴 스케줄러가 '튜토리얼 이후에 쓸' AR 모듈 패키지를 쥐도 새도 모르게 다운받아 런타임에 접착(Dynamic Linking)시키는 동적 조립 과정을 추적합니다.
  • Implement: 안드로이드 프로젝트를 Base와 Dynamic Feature로 찢어 모듈화한 뒤, 버튼 클릭 시 Play Core API(SplitInstallManager)를 통해 런타임 10MB 분할 팩을 다운받고 상태 리스너(Downloading ightarrow ightarrow Installed)에 따라 프로그레스바를 그리는 온디맨드 로직 구축.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
Tree Shaking 거대한 숲(코드 베이스)에서 나무를 흔들어 닿지 않는(사용되지 않는) 죽은 코드와 라이브러리를 바닥에 떨어뜨려 지워버리는 가위질입니다. 기본 빌드 최적화 Dead Code Elim. vs. Minification 난독화(이름 바꾸기)만 켜면 코드가 지워진다는 착각 Primary core
App Bundle (AAB) 앱의 모든 코드와 이미지를 부위별로 포장한 거대한 상자로, 플레이스토어가 유저 기기에 맞게 부위(APK Splits)만 꺼내 배달하는 포맷입니다. 권장 스토어 배포 App Thinning vs. Fat APK AAB를 기기에 직접 USB로 설치할 수 있다는 오해 (서버가 쪼개야 함) Industry Docs core
App Thinning (iOS) 애플 앱스토어가 사용자 아이폰 기종(해상도 @2x, @3x 및 칩셋 아키텍처)에 불필요한 에셋을 제외하고 날씬하게 패키징해주는 기술입니다. 실무 배포 최적화 Bitcode vs. Universal Binary 개발자가 직접 기기별로 5개의 앱을 빌드해서 올려야 한다는 옛날 착각 Industry Docs core
On-demand Delivery 유저가 특정 버튼(예: 증강현실 필터)을 누르는 순간, 스토어 서버에서 해당 모듈만 추가로 다운받아 런타임에 결합하는 지연 다운로드입니다. 심화 모듈화 Dynamic Feature vs. Base Module 한 번 설치된 앱은 이후 바이너리가 추가될 수 없다는 정적 컴파일 맹신 Industry Play core

8. References

Primary References

  • [CS2023: Software Engineering / Architecture] — 컴파일러 최적화 파이프라인, 죽은 코드 제거 알고리즘 및 링커(Linker) 메모리 맵.
  • [SWEBOK v3: Software Construction] — 모바일 플랫폼 한계(Bandwidth/Storage Constraint) 극복을 위한 코드 스플리팅 기법.

Secondary References

  • [LLVM Compiler Infrastructure] — Bitcode 중간 언어(IR) 최적화 과정과 앱 시닝(App Thinning)의 서버 사이드 바이너리 재조립 룰.
  • [Vector Graphics and Rasterization] — SVG 패스 파싱 및 GPU 래스터라이제이션 시 해상도 무관성(Resolution-independence) 보장.

Industry References

  • [Google Play: Shrink, obfuscate, and optimize your app] — R8 프로가드 룰셋팅 제어, -keep 매니페스트 보호 정책 및 런타임 에러(MissingMethodException) 방어.
  • [Apple Developer: Reducing your app's size] — On-Demand Resources (ODR) 태그 설정 및 슬라이싱(Slicing) 자산 카탈로그(Asset Catalog) 최적화.

9. Final Checklist

Primary Checklist

  • 배포용 빌드 생성 시 코드 축소 및 난독화 옵션(R8/Proguard, minifyEnabled)을 켜서 앱 바이너리 용량을 물리적으로 깎아내었는가?
  • 런타임 리플렉션(Reflection)이나 직렬화(JSON GSON)를 사용하는 데이터 클래스가 Tree Shaking에 의해 강제 삭제되지 않도록 -keep 방어 룰(규칙)을 정확히 명시했는가?

Secondary Checklist

  • 무거운 PNG나 JPG 비트맵 이미지를 해상도가 깨지지 않고 용량이 1/10인 벡터(VectorDrawable/SVG)나 WebP 포맷으로 압축 치환(Convert)했는가?
  • 일반 거대 APK 파일 배포 대신 Android App Bundle(AAB) 포맷으로 스토어에 업로드하여, 유저 기기(해상도, 아키텍처, 언어)에 맞는 코드만 분할 다운로드(App Thinning)되도록 구성했는가?

Industry Checklist

  • 초기 앱 설치 다운로드 장벽을 낮추기 위해, 한 달에 한 번 접근할까 말까 한 방대한 리소스(게임 에셋, 필터링 머신러닝 모델 등)를 Dynamic Feature Module (온디맨드)로 분리했는가?
  • iOS 빌드 시 불필요한 x86 에뮬레이터 아키텍처 슬라이스가 아카이브(Archive) 바이너리에 포함되어 앱스토어 용량 50MB 제한(Cellular 다운로드 경고)을 초과하지 않도록 링커(Linker) 플래그를 정돈했는가?

태그

mobile-devops-sre-mechanicsbinary-size-resource-optimization-mechanicsbinary-sizeresource-optimization-mechanicsmobilecross-platform-physicsmechanicsmobile-devopssre-mechanicsbinarysizemobile-dev-ops

Mobile Performance & Observability

1 / 2