Search

200MB 모듈을 팀 단위로 해결하기: 당근 숏폼팀의 On-demand Dynamic Feature Module 도입

URL
생성 일시
2026/02/27 11:06
최종 편집 일시
2026/02/27 11:06
태그
당근
파일과 미디어
|| 안녕하세요. 당근 숏폼팀 안드로이드 엔지니어 Bob이에요. 당근 스토리는 동네 가게와 일상을 1분 이내 영상으로 공유하는 지역 기반 숏폼 서비스예요. 동네 맛집, 운동, 미용실 같은 가게 이야기부터 일상적인 동네 소식까지, 우리 동네 사람들에게 자연스럽게 노출되는 게 특징이에요. 비즈니스, 부동산, 모임 등 당근의 여러 서비스에서도 숏폼을 활용하고 있고요. 현재 당근 스토리는 국내에서만 운영되고 있어요. 글로벌 앱에는 아직 숏폼 기능이 포함되어 있지 않죠. 편집 기능이 만든 고민 당근 앱은 MAU 2000만이 넘는 대규모 서비스로, 멀티모듈 구조로 되어 있어요. 숏폼팀도 shortform 모듈 안에서 독립적으로 개발하고 있죠. 당근 스토리에 비디오 편집 기능을 추가했을 때, 이 모듈의 용량이 200MB가 됐어요. 필터, 이펙트, 스티커 같은 리소스가 전부 SDK에 번들로 들어 있었거든요. 용량을 줄여야겠다는 게 첫 생각이었어요. 우선 리소스를 전부 CDN으로 전환하는 작업부터 시작했어요. 필요할 때만 다운로드하는 구조로 바꿨더니, 새 필터나 이펙트를 앱 배포 없이 반영할 수 있게 됐고 A/B 테스트도 유연해졌어요. 이 과정에서 용량이 200MB → 40MB로 줄었죠. 하지만 40MB도 여전히 가벼운 수치는 아니었어요. 영상 편집은 소수만 사용하는 기능인데, 글로벌 전체 사용자에게 40MB가 함께 설치되는 건 고민이었어요. 우리 팀의 실험이 전체 사용자 경험에 영향을 주지 않았으면 좋겠다 — 이게 팀의 결론이었고, DFM 도입으로 이어졌어요. Dynamic Feature Module이란? DFM(Dynamic Feature Module)은 앱의 특정 기능을 별도 모듈로 분리해서 필요할 때만 다운로드할 수 있게 해주는 Android App Bundle의 기능이에요. 배포(Delivery) 방식은 세 가지가 있어요: Install-time Delivery: 앱 설치 시 함께 설치 On-demand Delivery: 사용자 요청 시 다운로드 Conditional Delivery: 조건(국가, API 레벨 등)에 따라 자동 설치 당근은 이미 Conditional Delivery로 국가별 모듈을 제공한 경험이 있어요. 설치 시점에 국가별 코드를 자동으로 내려보내는 방식이었죠. (App Bundle의 Dynamic Delivery로 국가별 모듈 제공하기) 이번에는 설치 시점이 아니라 사용자가 필요할 때만 다운로드해야 하는 상황이었기 때문에, On-demand Delivery를 선택했어요. On-demand Delivery로 전환하면, 편집 기능을 쓰지 않는 대다수 사용자와 글로벌 사용자는 설치 시 40MB를 받지 않아도 앱을 사용할 수 있어요. 동시에 사용자가 편집 기능을 처음 쓰는 순간의 경험도 함께 설계해야 했어요. DFM 다운로드를 어떻게 자연스럽게 보여줄지, 네트워크 이슈가 있을 때 어떻게 안내할지 같은 운영 과제도 함께 고민했죠. 실제 사용자 플로우 편집 버튼을 누르면 편집 모듈이 다운로드되고, 이후에는 로컬에 설치되어 바로 사용 가능해요. 개발 과정에서 마주한 이슈들 처음에는 “DFM에서 코드영역을 완전히 분리하자”고 생각했어요. 네이티브 라이브러리(SO 파일)뿐 아니라 기능 코드, DI까지 모두 DFM으로 옮기려 했죠. 하지만 막상 해보니, “기술적으로 가능한 것”과 “운영에서 효율적인 것” 사이에는 간극이 있었어요. DFM을 사용하게 되면 모듈구조가 base 모듈과 feature(DFM) 모듈 두 가지로 나뉘어요. base 모듈은 앱 설치 시 항상 포함되는 기본 모듈이고, feature 모듈은 필요할 때 추가로 다운로드되는 모듈이에요. 아래 이슈들은 이 구조에서 발생한 것들이에요.1. Hilt/DI 제약 Hilt는 컴파일 타임에 모든 모듈의 의존성 그래프를 합쳐서 코드를 생성해요. 그런데 DFM은 base와 별도로 빌드되기 때문에, Hilt의 어노테이션 프로세서가 DFM 안의 @Inject나 @Module을 base 빌드 시점에 알 수 없어요. 그래서 DFM에서는 Hilt를 그대로