멀티 국가 앱에서 Pretendard JP 도입하기
가볍게, 그리고 필요한 사람에게만
2026년 4월 17일Zemic

안녕하세요. 오늘의집 일본커머스팀에서 Android 개발을 하고 있는 Zemic입니다. 현재 오늘의집 앱의 국내 서비스에는 Pretendard 폰트가 적용되어 있습니다.

이번 글에서는 일본 서비스에도 디자인 가이드와 일관된 사용자 경험을 제공할 수 있도록 Pretendard JP 폰트를 적용한 과정과, 그 과정에서 겪은 시행착오를 공유리고자 합니다.


0. 프롤로그 — 분명 폰트가 적용되어 있는데 다른 폰트가 노출되고 있다

어느날 "폰트의 weight 값이 디자인 가이드에 비해 얇아 보인다"는 버그 제보를 받았습니다. 처음에는 단순히 기종의 차이에서 발생한 이슈라고 생각했습니다. 하지만 혼자 원인을 분석할수록 쉽게 설명되지 않았고, Android Weekly Time-out에서 비슷한 이슈를 경험해 본 분이 있는지 확인해 보기로 결정했습니다.

“혹시 폰트가 제대로 적용되지 않은 건 아닐까요?”

동료의 이 한마디를 계기로 다시 비교해 본 결과, 실제 화면에 노출되는 폰트가 Pretendard와 다르다는 사실을 확인할 수 있었습니다.


1. 왜 다른 폰트가 노출되고 있었을까

FontForge라는 도구를 활용하면 폰트 파일의 세부 내용을 확인해 볼 수 있습니다. 확인 결과 당시 적용된 폰트 파일은 특수문자 / 영어 / 한글자모 / 한글문자집합으로 구성되어 있었고, 일본어와 한자는 포함하고 있지 않았습니다.


다시 비교해 보니 숫자와 영어는 동일했지만, 일본어와 한자가 시스템 폰트로 대체 렌더링되고 있었던 것으로 추정할 수 있었습니다.


2. 폰트만 적용하면 끝날 것이라 생각했지만…

Pretendard는 일본어 환경을 고려한 Pretendard JP 폰트를 제공하고 있습니다. 처음에는 기존 폰트 파일을 Pretendard JP 폰트 파일로 교체하면 해결되는 비교적 단순한 작업으로 생각했습니다.

https://cactus.tistory.com/306


하지만 폰트를 내려받아 확인해 보니, 현재 적용된 폰트 파일에 비해 Pretendard JP 파일의 크기가 훨씬 컸습니다.


만약 이 폰트를 그대로 적용하면 APK 파일이 지금보다 10MB 증가하게 됩니다. 일본 사용자를 위해 일본어 폰트가 추가되어 앱 용량이 증가하는 것은 자연스러운 일이지만, 이 방식을 그대로 적용하게 되면 일본 서비스를 사용하지 않는 한국과 미국 사용자도 동일한 폰트를 함께 내려받아야 한다는 문제가 있었습니다. 그래서 단순 교체보다는 필요한 사용자에게만 필요한 리소스를 제공하는 방식이 더 적절하다고 판단했습니다.


3. 폰트 파일 경량화하기

✔️ 우리는 이미 경량화된 폰트 파일을 쓰고 있었다

사실 당시 국내 서비스에 적용된 폰트 파일도 Pretendard 폰트 파일에서 경량화된 파일이었습니다. 정확히는 "특수문자 / 영어 / 한글자모 / 한글문자집합(KS X 1001)" 만 남기고 모두 제거된 경량화 파일이었습니다.

*KS X 1001 : 한국산업규격 표준으로 등록된 자주 사용되는 한글 음절 집합


이를 바탕으로 Pretendard JP 역시 원본 전체를 적용하기보다, 일본 서비스에 필요한 문자만 선별해 추가하는 방식이 가능하다고 판단했습니다. 한자 / 히라가나 /가타카나 외에도 자주 사용되는 문자가 있는지 일본어 통역사분께 확인을 요청드렸고,  감사하게도 전각기호, 반각기호, 기타 자주 쓰이는 특수문자 목록까지 함께 정리해주셨습니다.


✔️ 목록에 맞게 폰트 파일을 경량화해 보자

폰트를 추가하고 제거하기 위한 도구로 FontForge와 TTFont라는 선택지가 있었습니다. 처음에는 폰트 파일 분석을 위해 FontForge GUI를 사용하였기에 라이브러리도 FontForge로 수정을 시도했습니다. 하지만 이 방법에는 문제가 있었습니다.

예를 들어, 이미지의 “國內發送”처럼 일정한 형태로 폰트 패딩이 적용되어야 하는 문자들이, FontForge 로 생성한 파일에서는 “tommy”처럼 상단 패딩이 과도하게 추가되는 현상이 발생했습니다.

더 이상했던 점은 FontForge에서 파일을 열어 아무 수정 없이 다시 내보내기만 해도 동일한 이슈가 발생했다는 점입니다. 이와 달리 TTFont에서는 동일한 문제가 발생하지 않았기 때문에 최종적으로 TTFont를 활용해 경량화 작업을 진행하게 되었습니다.

이후 다양한 상황에서 대응할 수 있도록 Claude를 활용하여 아래와 같은 세 가지 도구를 만들었습니다.

  • [A] 지정된 폰트에서 대상 폰트로 유니코드/GlyphID에 해당하는 폰트를 복사하는 도구 (FontForge 기반)
  • [B] 지정된 폰트의 유니코드 목록을 추출하는 도구 (TTFont 기반)
  • [C] 지정된 폰트에서 제공된 유니코드 목록에 포함되지 않은 폰트를 제거하는 도구 (TTFont 기반)


이 도구들을 위와 같은 순서로 적용해 경량화된 Pretendard JP 파일을 생성할 수 있었습니다.

그 결과, 일본어 / 한자 / 전각기호 / 반각기호 / 특수문자만 남기고 나머지를 제거해, 각 3.7MB 수준이던 원본 폰트 파일을 2.4MB까지 줄이며 약 35%를 절감할 수 있었습니다.


4. 일본어 서비스 사용자에게만 폰트가 추가되게 하는 방법

이후 진행된 Android Weekly Time-out에서 경량화된 폰트 파일을 도입하자는 의견을 제시했습니다. 이에 “다른 서비스 사용자에게는 영향이 없으면 좋겠다”는 피드백과 함께 “Downloadable Font와 Dynamic Feature Module”이라는 아이디어를 제안받았습니다.

들어가기에 앞서 — AAB에서 로컬에 맞게 Font Resource를 자연스럽게 제공할 수는 없었을까

사실 가장 간단한 방법은 기존 폰트 파일을 pretendard_bold.otf 로 두고, 경량화된 Pretendard JP 폰트를 pretendard_bold.otf (b+ja)로 두는 방법입니다. 이렇게하면 Play Store에서 다운로드 시 일본 사용자에게만 Pretendard JP 폰트가 적용되게 할 수 있습니다.

이 방법을 적용하려면 app gradle 에서 languageenableSplit = true로 변경하는 작업이 필요합니다. 여기서 언급된 language enabledSplit Flag는 App Bundle 에서 각 사용자의 기기에 알맞는 언어 리소스가 포함된 APK 파일을 제공할지 여부를 조절하는 Flag 입니다.

하지만 오늘의집 앱은 서드파티 라이브러리로 인하여 발생하는 에러로 이 Flag가 비활성화되어 있으며, 여러 서비스에서 언어에 맞는 문자열을 제공하기 위한 기반 정책 또한 이런 환경을 기반으로 수립되어 있었습니다. 따라서 이 Flag를 true로 변경하기 위해선 이에 대한 재논의가 필요했고, 현시점에선 해결하려는 문제에 비해 변경 범위가 지나치게 크다고 판단해 채택하지 않았습니다.


1) Downloadable Font

https://developer.android.com/develop/ui/views/text-and-emoji/downloadable-fonts

Downloadable Font는 필요한 폰트를 FontProvider에 다운로드해 두었다가, 해당 폰트를 필요로 하는 앱에서 요청이 들어오면 폰트를 제공하는 기능입니다. 그 중 Google에서 제공하는 Font Provider를 사용하면 폰트가 처음 적용되는 순간에는 시스템 폰트가 잠시 노출될 수 있지만, 앱 내에 폰트 파일 리소스를 직접 추가할 필요가 없다는 강점이 있어서 최우선적으로 검토했습니다.


하지만 안타깝게도 Downloadable Font를 채택하지 않았습니다. Google에서 제공하는 Font Provider를 사용하려면 Google Fonts에 등록된 폰트만 사용할 수 있는데 Pretendard 폰트는 Google Fonts에 등록되어 있지 않았기 때문입니다. 물론 Font Provider를 직접 구현하는 방법도 있습니다. 하지만 이 경우 Google의 인프라를 활용하는 방식이 아니라 앱에 번들로 넣거나, 폰트 다운로드 로직을 직접 구현해야하는 복잡도가 높은 방식이어서 채택하기에는 부적절하다고 생각했습니다.


2) Dynamic Feature Module

Dynamic Feature Module은 Google Play 시스템에서 앱 다운로드 시점에 특정 조건에 해당하는 사용자에게만 함께 전달하는 동적 제공 Module입니다. 이때 '특정 조건'에는 국가도 포함할 수 있기에, 일본 사용자에게만 일본어 폰트 파일이 포함된 Module을 제공하는 형태의 아이디어입니다. 기존 오늘의집 안드로이드 코드 구조를 간략하게 표현하면, 사내 디자인 시스템이 별도의 모듈로 분리되어 있고 각각의 feature module이 이를 참조하는 형태로 구현되어 있습니다.


이에 따라 일본 사용자에게 JP 전용 폰트 제공을 위해 design-system 모듈 하위로 일본 사용자에게만 추가되는 dynamic-feature-module을 추가하였습니다. 이렇게 하면 FontFamilyFactory에서 SplitInstallManagerFactory를 통해 dynamic-module의 존재 여부를 확인하고, 적절한 폰트로 사용자에게 제공할 수 있는 구조로 작성할 수 있게 됩니다. 만일 존재하지 않더라도 Fallback으로 한국어 리소스가 제공되는 구조입니다.


이러한 구조는 새로운 조건의 dynamic-feature-module 을 추가하고 제거하기에 용이합니다. 그리고 현재는 한국어 폰트 리소스가 모두 합쳐 1MB가 조금 넘는 작은 용량이기에 fallback 용도로 사용하기 위해 분리하지 않았지만, 원한다면 dynamic-feature-module 로 분리하여 대응할 수 있는 유연한 구조입니다.


결과

그 결과 일본 외 서비스 사용자에겐 기존과 동일한 경험을 제공하고, 일본 서비스 사용자에게 7.6MB의 용량 추가로 디자인 가이드와 동일한 경험을 제공할 수 있었습니다.


5. 마치며

처음에는 단순한 폰트 교체 작업이라고 생각했지만, 실제로는 더 나은 해결 방식을 찾기 위해 여러 선택지를 검토하고 조정해야 하는 과정이었습니다. 이 여정은 출발점을 열어주신 QA 담당자분들, 해결 과정에서 다양한 의견과 도움을 주신 Android 팀원분들, 번역가분, 디자이너분들 덕분에 가능했습니다.

일본 서비스의 크고 작은 사용성 개선 작업은 지금도 계속되고 있습니다. 앞으로도 새로운 시도와 함께, 더 나은 경험을 만들기 위한 이야기를 기술 블로그를 통해 공유드리겠습니다. 많은 관심 부탁드립니다!

오늘의집에서 당신을 찾고 있습니다!
Senior Backend Engineer, Tech Lead & Manager, CommerceSenior Frontend Engineer, Tech Lead & Manager, CommerceSenior Backend Engineer, AdsSenior Backend Engineer, Core PlatformSenior Machine Learning Engineer, SearchSenior Machine Learning Engineer, Vision/GenAISenior Machine Learning Engineer, Ads & RecommendationSenior Android Engineer, Client FoundationSenior Cloud EngineeringBackend Engineer, Core PlatformBackend Engineer, Interior & LifeBackend Engineer, CommerceBackend Engineer, AdsFrontend Engineer, ContentFullstack Engineer, Life ServiceFullstack Product Engineer, AI AgentiOS Engineer, ContentMachine Learning Engineer, ML PlatformMachine Learning Engineer, Ads & RecommendationMachine Learning Engineer, Ads & Recommendation (전문연구요원)Cloud EngineerSenior Data Analytics EngineerData Analytics EngineerDatabase Reliability EngineerSenior Data EngineerData Engineer[오늘의집페이] Fullstack Engineer[오늘의집페이] Frontend Engineer
목록으로 돌아가기