한국의 개발자들을 위한 Google for Developers 국문 블로그입니다.
안드로이드 인스턴트 앱 다운로드 크기를 줄이는 모범 사례를 만나보세요.
2017년 9월 26일 화요일
<블로그 원문은
여기
에서 확인하실 수 있으며, 블로그 번역 리뷰는 양찬석(Google)님이 참여해 주셨습니다.>
게시자: Maru Ahues Bouza, Google Play 개발자 관계 파트너
안드로이드 인스턴트 앱은 더욱 풍부하고 자연스러운 사용자 경험을 제공합니다. 앱을 미리 설치하지 않아도 체험해 볼 수 있으므로 사용자 참여를 촉진할 수 있습니다. 하지만 모바일 웹페이지와 비슷한 속도로 앱이 실행되기 위해서는, 앱을 빠르게 다운로드하고 실행할 수 있어야 합니다. 이를 위해, 특정 URL에 대한 응답으로 로드되는 바이너리를 가급적 작게(4MB 이하로) 유지해야 합니다. 바이너리가 작을수록 인스턴트 앱은 더 신속하게 설치되고, 더 쾌적한 사용자 경험을 제공할 수 있습니다. 이 문서에서는 애플리케이션 구조와 바이너리 크기를 관리하는 데 참고할 수 있는 모범 사례를 공유합니다. 설명된 내용들은 설치 가능한 앱의 바이너리 크기를 최적화하는데도 적용될 수 있습니다.
코드베이스 리팩터링
앱 바이너리 크기를 효율적으로 관리하기 위해, 앱을
기능 모듈
(Feature Module) 단위로 리팩터링 하는 것이 권장됩니다. 앱 바이너리 크기가 작고, 제공하는 기능이 많지 않은 경우도 그렇습니다. 새로운 기능을 추가해야할 때, 기존 앱 바이너리 크기에 영향을 주지 않고 더 많은 기능을 신속하게 추가할 수 있습니다. 인스턴트 앱을 위한 별도의 코드 베이스를 만드는 대신, 설치 가능한 애플리케이션과 인스턴트 애플리케이션을 모두 생성하는 통합된 모듈형 코드베이스를 구축할 수 있습니다. 개별 프로젝트와 코드를 유지해야 하는 부담이 줄어들고 두 애플리케이션에 걸쳐 깔끔하게 프로젝트 구조를 만들 수 있습니다.
인스턴트 앱을 미리 적용한 파트너의 경험을 바탕으로 생각해 볼 때, 코드베이스 리펙터링 작업이 다운로드 되는 바이너리 크기에 가장 큰 영향을 미칠 거라 생각합니다. 하지만 동시에 가장 큰 투자가 필요한 부분이기도 합니다. 성공적인 코드베이스 리팩터링을 위한 한 가지 팁은, 단일(기본) 모듈부터 시작한 후 관련 부분을 기능 모듈로 이전하는 방식으로 리팩터링을 진행하는 것 입니다.
참고로, 인스턴트 앱의 크기 제한은 로컬로 빌드된 바이너리에 적용되지 않으므로 인스턴트 앱을 개발하는 동안 바이너리 크기에 대해 염려할 필요는 없습니다. Play Developers Console을 통해 바이너리를
개발 트랙
(개발 과정에서 인스턴트 앱을 신속히 배포할 수 있는 특별 트랙)에 게시할 수도 있습니다. 개발 트랙의 크기 제한은 10MB이고, [
1
,
2
] 바이너리가 개발 트랙을 거치고 나면 4MB 제한이 적용됩니다.
각 기능 모듈에는 주어진 URL에 대응하는 진입점(즉, Activity)이 하나 이상 있을 수 있습니다. 단일 코드베이스를 다중 모듈로 분할할 때 기능마다 각기 다른 진입점을 구성할 수 있으며, 필요에 따라 관련 기능을 추가로 로드할 수 있습니다. 특정 진입점에 다운로드해야 하는 총 바이너리는 4MB 미만이어야 하므로, 기능 모듈과 기본 모듈을 합친 크기가 4MB 미만이어야 한다는 점을 유의하시기 바랍니다.
각각의 기능과 기능을 수행하기 위한 Activity, 및 해당 기능에 진입하기 위한 URL 매핑을 먼저 정의한 후각 진입점에 대한 바이너리 크기를 줄이는 방향으로 리팩터링 작업을 구성하는 것이 좋습니다.
라이브러리를 어떻게 포함할지도 고려해야합니다. 특정 기능 모듈에만 필요한 라이브러리의 경우 기본 기능 모듈에 추가하는 대신, 해당 기능 모듈에만 라이브러리를 포함시킬 수 있습니다. 예를 들어 라이브러리 X, Y, Z에 종속되는 애플리케이션이 있다고 가정해 봅니다. 그러면 모든 종속 사항을 기본 모듈의 gradle.build 파일에 정의하여, 기본 모듈에 모든 라이브러리를 패키징할 수 있습니다. 하지만 기능 모듈의 코드에 라이브러리 Z만 필요한 경우 기본 모듈에서 해당 종속 사항만 기능 모듈로 이동하는 것이 합리적입니다. 여러 기능 모듈이 같은 라이브러리를 사용하는 경우에는 기본 모듈에 라이브러리를 유지하는 것이 좋습니다.
Lint 검사
많은 앱이 앱 내에 정의된 리소스 중 일부만을 사용합니다. 안드로이드 스튜디오에서는 사용되지 않는 리소스에 대한 Lint 검사가 기본적으로 제공됩니다. Alt+Ctrl+Shift+I(Mac OS의 경우 Cmd+Alt+Shift+I)를 누르고, 'unused resources'를 입력한 후 'Unused resources Android|Lint|Performance' 검사를 시작합니다. 이 검사는 설치 가능한 APK의 크기를 줄이는 데도 도움이 됩니다.
문자열 리소스
리소스와 유사하게, 문자열도 주의해야 합니다. 문자열 중에는 사용되고 있지 않은 문자열도 있을 수 있습니다. 일반적으로, 사용되지 않는 문자열 리소스를 제거하면 애플리케이션 크기를 상당히 줄일 수 있습니다. 애플리케이션이 다중 언어를 지원하는 경우 현지화된 리소스의 수를 줄이고자 할 수 있습니다. 그러면 일반적으로 리소스 자산에서 상당히 많은 양이 제거됩니다. 이는 앱이 몇 개의 언어만 지원하는데 여러 언어로 된 메시지를 포함하는 AppCompat 라이브러리를 사용하는 경우 특히 중요합니다.
resConfig
를 사용하여 특정 리소스 구성만 선택할 수 있습니다.
힌트: 일반적으로 '
auto
'를 사용하여 타사 라이브러리에서 가져오는 구성을 제한할 수 있습니다.
WebP로 전환
PNG 대신
WebP 이미지
로 전환하면
Drawable Resource 크기
를 상당히 줄일 수 있습니다. 안드로이드 인스턴트 앱은 WebP 형식의 모든 기능(투명성, 무손실 등)을 지원합니다. 다만, 애플리케이션 런처 아이콘은 PNG 형식을 사용해야 합니다. 일반적으로 앱 아이콘은 mipmap- 디렉토리에 저장됨으로 큰 문제는 없을 것 입니다. 이전 버전과 호환 가능한 솔루션이 필요한 경우, APK 모듈에 원래 PNG 이미지를 포함해야 하며 그러면
WebP 리소스가 자동으로 재정의
됩니다(기본 소스 집합이 AAR/기능 모듈의 모든 리소스를 재정의함). [
4
]
물론, VectorDrawable을 사용하면 훨씬 더 많은 공간을 절약할 수 있지만 VectorDrawable을 사용하는 데는 코드 변경이 필요합니다. 반면, 위에 언급한 인스턴트 앱에는 WebP 이미지를 사용하고 설치 가능한 APK에는 PNG 이미지를 사용하는 트릭의 경우 코드를 수정할 필요가 없습니다.
런타임에 Asset 다운로드
인스턴트 앱 APK에 모든 리소스를 패키징할 필요는 없습니다. 애플리케이션이 실행 중에 추가 Asset을 다운로드할 수 있기 때문입니다. 이 접근 방법을 통해 앱은 필요한 Asset을 다운로드할 수 있습니다. 코드베이스를 상당히 변경해야 할 수 있지만, APK의 크기 감소에 큰 도움이 됩니다. 리소스를 축소해도 앱 기능 모듈 크기가 제한보다 낮게 줄어들지 않는다면, 이러한 방법을 검토해볼 수 있습니다.
네이티브 라이브러리 검토
사용중인 라이브러리에는 인스턴트 앱에서 전혀 사용되지 않는 네이티브 코드가 포함되어 있을 수 있습니다. 따라서 첫 번째 단계로 APK 내에 패키징된 네이티브 라이브러리를 검토하여 인스턴트 앱에 실제로 사용되는 라이브러리만 포함되어 있는지 확인해야 합니다.
APK Analyzer
(Build -> APK Analyzer…)를 사용하여 컴파일된 APK를 살펴봐야 합니다. [
5
]
외부 라이브러리 검토
다음으로, 앱의 코드와 연결된 모든 외부 라이브러리의 목록을 검토합니다. 의존성 전이 (transitive dependencies)에 의해 몇몇 예기치 않은 항목이 포함되어 있을 수 있습니다. 의존성 전이는 프로젝트가 참조하는 라이브러리가 다른 라이브러리를 참조하고 있는데, 그 다른 라이브러리가 또 다른 라이브러리에 종속될 수 있을 때 발생합니다. 때로는 이러한 의존성 전이 과정에서 전혀 필요하지 않은 라이브러리(예: 코드에서 절대 사용하지 않는 JSON 처리 라이브러리) 같은 예기치 않은 항목이 포함될 수 있습니다. 자세한 내용은 Gradle 사용자 가이드의 '
의존성 전이 항목 제외
' 섹션을 참조하세요.
안드로이드 스튜디오에는 프로젝트의 외부 종속 항목 분석에 사용할 수 있는 여러 가지 유용한 도구가 포함되어 있습니다. 어떠한 경우든 Project 뷰부터 살펴보면 도움이 됩니다.
'Project' 뷰에는 'External libraries'라는 섹션이 표시됩니다. 여기서 의존성 전이 항목을 포함하여 프로젝트에서 사용되는 모든 라이브러리를 볼 수 있습니다.
기본 기능 모듈의 크기를 더 줄이려면 코드 종속 항목과 외부 라이브러리에 유의해야 합니다. 'Project' 뷰를 확인하고 프로젝트에 필요하지 라이브러리를 찾습니다. 또한, 같은 기능을 제공하는 라이브러리도 찾습니다(예: 이미지 로드/캐싱을 지원하는 여러 라이브러리). [
4
]
APK Analyzer
도구를 사용하여 여러 빌드를 비교할 수도 있습니다. 이는 인스턴트 APK에도 효과가 있습니다.
마지막으로, 의존성 전이 항목을 검토하고 필요하지 않은 항목을 제외합니다.
gradle -q :MODULE:dependencies --configuration compile
명령어를 사용하여 종속 항목 그래프를 검토합니다. 자세한 내용은
Gradle 문서
에서 확인할 수 있습니다.
기타 팁
안드로이드 스튜디오 3.0에는 App Links Assistant 도구가 포함되어 있습니다. 이 도구는 필요한 인텐트 필터를 생성하는 데 도움이 될 수 있으며 프로젝트를 여러 모듈로 분할하는 데도 도움이 됩니다. [
3
]
크기 제한을 초과하지 않는 크기의 인스턴트 앱 번들을 구축했으면 이제는 빌드 프로세스가 최신 상태인지 확인하세요. 애플리케이션 패키지와 인스턴트 앱 APK가 '
APK Signature Scheme v2
'를 사용하여 서명되었는지 확인합니다. 최신 버전의 SDK 도구를 사용하여 APK를 서명하면 모든 작업이 자동으로 수행됩니다. 하지만 빌드 아티팩트를 수동으로 서명하는 경우에는 jarsigner를 사용하지 말고 그 대신
apksigner
로 전환해야 합니다.
또한, 인스턴트 런타임 환경에 맞게 앱 코드를 변경하는 데 활용할 수 있는 유용한 팁이 몇 가지 있습니다.
InstantApps.isInstantApp(...)
을 기반으로 인스턴트/설치 가능한 애플리케이션에 대해 작은 코드 분기를 구성할 수 있습니다. 또한, 공유 인텐트를 사용할 때는 코드가 기기에 설치된 애플리케이션을 명시적으로 열거하지 않는지 확인하세요. 인스턴트 앱 보안 모델에서 이를 허용하지 않습니다. 간단히 일반 Intent.createChooser()를 사용하여 가능한 모든 작업 목록을 사용자에게 표시하면 됩니다.
기존 안드로이드 애플리케이션용 인스턴트 앱을 개발하는 데 필요한 작업은 개발자에 따라 다르며, 애플리케이션이 현재 구성된 방식에 따라 상당한 영향을 받습니다. 몇몇 경우, 프로젝트가 이미 다중 모듈로 구성되어 있으므로 쉬울 것입니다.
다른 개발자의 안드로이드 인스턴트 앱 사용 사례
끝으로, 인스턴트 앱을 이미 적용한 개발자들이 공유한 다음 정보를 참고해보시기 바랍니다.
Buzzfeed
:
From Westinghouse to Android Instant apps, a BuzzFeed Journey
Realestate.com.au
:
Building the realestate.com.au Android Instant App
WillowTree
:
An introduction to Android Instant Apps
Jet.com
:
Make Your App Instant
Vimeo
:
Android Instant Apps, step-by-step: how Vimeo went about it
Ticketmaster
:
Ticketmaster Demonstrates Cutting Edge Android Instant Apps Technology at Google I/O
Domain
:
Making the Domain Android App Instant
안드로이드 개발자 웹사이트를 방문하여
안드로이드 인스턴트 앱 작업을 시작
해 보고 다른 개발자가 들려주는
인스턴트 앱 성공 사례를 더 확인
해 보시기 바랍니다.
Contents
ML/Tensorflow
Android
Flutter
Web/Chrome
Cloud
Google Play
Community
Game
Firebase
검색
Tag
인디게임페스티벌
정책 세미나
창구프로그램
AdMob
AI
Android
Android 12
Android 12L
Android 13
Android 14
Android Assistant
Android Auto
Android Games
Android Jetpack
Android Machine Learning
Android Privacy
Android Studio
Android TV
Android Wear
App Bundle
bootcamp
Business
Chrome
Cloud
Community
compose
Firebase
Flutter
Foldables
Game
gdg
GDSC
google
Google Developer Student Clubs
Google Play
Google Play Games
Interview
Jetpack
Jetpack Compose
kotlin
Large Screens
Library
ma
Material Design
Material You
ML/Tensorflow
mobile games
Now in Android
PC
Play Console
Policy
priva
wa
wear
Wearables
Web
Web/Chrome
Weeklyupdates
WorkManager
Archive
2024
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2023
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2022
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2021
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2020
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2019
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2018
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2017
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2016
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2015
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2014
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2013
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2012
12월
11월
10월
9월
8월
7월
6월
5월
3월
2월
1월
2011
12월
11월
Feed