앱 크기 최적화 — Tree Shaking, Deferred Components
앱 크기 최적화 — Tree Shaking, Deferred Components
앱 크기가 클수록 다운로드 전환율이 떨어집니다. Google에 따르면 APK 크기가 6MB 증가할 때마다 설치율이 1% 감소합니다. Flutter 앱의 크기를 줄이는 방법을 정리해보겠습니다.
앱 크기 분석
# 앱 크기 분석 (Android)
flutter build apk --analyze-size
# 앱 크기 분석 (iOS)
flutter build ios --analyze-size
# 결과를 DevTools에서 시각화
# 터미널에 표시된 JSON 파일을 DevTools App Size 탭에서 열기
Tree Shaking
Dart는 빌드 시 사용하지 않는 코드를 자동으로 제거합니다(Tree Shaking). 하지만 몇 가지 주의할 점이 있습니다.
// Tree Shaking이 잘 동작하려면:
// 1. 사용하지 않는 import 제거
import 'package:huge_package/huge_package.dart'; // 전체 import 지양
import 'package:huge_package/only_needed.dart'; // 필요한 것만 import
// 2. Material과 Cupertino 중 하나만 사용
// 둘 다 import하면 두 프레임워크 모두 포함됨
import 'package:flutter/material.dart';
// import 'package:flutter/cupertino.dart'; // 불필요하면 제거
// 3. 사용하지 않는 패키지 정리
// pubspec.yaml에서 사용하지 않는 의존성 제거
에셋 최적화
이미지 압축
# 이미지 크기 확인
find assets -name "*.png" -exec ls -la {} \;
# WebP 형식으로 변환 (PNG/JPEG보다 30-50% 작음)
# Flutter는 WebP를 지원합니다
// WebP 이미지 사용
Image.asset('assets/images/photo.webp')
불필요한 에셋 제거
# pubspec.yaml — 폴더 전체 대신 필요한 파일만 등록
flutter:
assets:
- assets/images/logo.webp # 필요한 파일만
- assets/images/background.webp
# - assets/images/ # 폴더 전체는 불필요한 파일 포함 가능
폰트 최적화
flutter:
fonts:
- family: Pretendard
fonts:
- asset: assets/fonts/Pretendard-Regular.otf
weight: 400
- asset: assets/fonts/Pretendard-Bold.otf
weight: 700
# 사용하지 않는 두께는 포함하지 않기
Android 앱 번들 (AAB)
APK 대신 AAB로 빌드하면 Google Play가 디바이스에 맞는 리소스만 포함시킵니다.
# AAB 빌드 (권장)
flutter build appbundle
# 크기 비교
# APK: 모든 ABI(arm64, arm, x86) 포함 → 크기 큼
# AAB: 디바이스에 맞는 ABI만 배포 → 30-50% 작음
ABI별 APK 분리
# ABI별로 분리된 APK 생성
flutter build apk --split-per-abi
# 결과:
# app-armeabi-v7a-release.apk (32bit ARM)
# app-arm64-v8a-release.apk (64bit ARM)
# app-x86_64-release.apk (x86)
Deferred Components (지연 로딩)
앱의 일부 기능을 나중에 다운로드하는 방식입니다. Android의 Dynamic Feature Module을 활용합니다.
// 지연 로드할 라이브러리
import 'package:my_app/heavy_feature.dart' deferred as heavy;
// 필요할 때 로드
Future<void> _loadHeavyFeature() async {
await heavy.loadLibrary();
// 로드 후 사용
heavy.showHeavyScreen();
}
// UI에서 사용
ElevatedButton(
onPressed: () async {
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => const Center(child: CircularProgressIndicator()),
);
await _loadHeavyFeature();
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (_) => heavy.HeavyScreen()),
);
},
child: const Text('고급 기능'),
)
프로가드 (Android 코드 축소)
// android/app/build.gradle
android {
buildTypes {
release {
minifyEnabled true // 코드 축소
shrinkResources true // 리소스 축소
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
크기 최적화 체크리스트
| 항목 | 효과 |
|---|---|
| AAB 빌드 사용 | 30-50% 감소 |
| 이미지를 WebP로 변환 | 30-50% 감소 (이미지) |
| 불필요한 패키지 제거 | 가변적 |
| 폰트 서브셋 사용 | 폰트 크기 감소 |
| --split-per-abi | ABI별 분리 |
| 사용하지 않는 에셋 제거 | 가변적 |
| Deferred Components | 초기 크기 감소 |
| ProGuard 활성화 | 네이티브 코드 축소 |
앱 크기 기준
| 크기 | 평가 |
|---|---|
| ~10MB | 매우 작음 |
| 10-30MB | 일반적 |
| 30-50MB | 크지만 허용 범위 |
| 50MB+ | 최적화 필요 |
면접 포인트: Flutter 앱의 기본 크기(최소 약 5-6MB)는 Dart VM과 Flutter 엔진이 포함되기 때문입니다. 네이티브 앱보다 기본 크기가 크지만, AAB와 에셋 최적화로 충분히 관리할 수 있습니다.
정리
flutter build apk --analyze-size로 앱 크기를 분석하세요- AAB(App Bundle) 빌드는 디바이스 맞춤 리소스만 배포합니다
- 이미지는 WebP로 변환하고, 불필요한 에셋과 패키지를 정리하세요
- Tree Shaking이 잘 동작하도록 필요한 것만 import하세요
--split-per-abi로 ABI별 APK를 분리하면 크기가 크게 줄어듭니다- Deferred Components로 무거운 기능을 필요 시에만 다운로드할 수 있습니다
댓글 로딩 중...