Android
다시 쓰는 해외 여행 이야기 — 웹뷰에서 네이티브로
Ram여기어때
2025년 1월 3일
원문에서 보기 ↗안녕하세요, 여기어때컴퍼니 Android개발팀 램입니다.
우리가 제공하는 해외 숙소 서비스는 사용자 경험을 최적화하기 위해 지속해서 개선되고 있습니다. 하지만 기존 시스템은 기술적 한계로 인해 유지보수가 점점 더 어려워지고, 성능 저하 문제가 발생하기 시작했습니다. 이러한 문제를 해결하기 위해 Jetpack Compose를 활용한 네이티브 전환을 결정했으며, 이 과정에서 다양한 기술적 도전과 해결책을 찾아야 했습니다.
먼저, 기존 시스템의 한계를 잘 보여주는 예시로 아래 동영상을 준비했습니다.
https://www.youtube.com/watch?v=jDUITZUSWS0
왼쪽이 기존의 웹뷰 화면, 오른쪽이 개선된 네이티브로 개발된 화면입니다. 화면 로딩 속도가 확연히 빨라진 것을 확인 할 수 있으며, Progress 동안에 유저의 행동을 Block하지 않는 것을 볼 수 있습니다.
이번 글에서는 이러한 전환 과정에서 겪었던 도전, 해결책, 그리고 기술적 여정을 공유하고자 합니다.
기존 해외 숙소
기존 해외 숙소 시스템은 웹뷰기반으로 설계되어 있었습니다. 이 방식은 UI를 빠르게 구현할 수 있다는 장점이 있었지만, 시간이 지남에 따라 여러 가지 한계가 드러났습니다.
- 화면 렌더링에 이슈가 있었습니다.
- 특히 홈의 경우 렌더링 시간이 2초이상 소요되는 경우가 잦았습니다.
- 네트워크 지연이 일어나거나, 클라이언트 기기의 웹뷰에 문제가 있는 경우 빈 화면을 노출하는 경우도 있었습니다.
- 유지보수의 복잡성이 증가했습니다.
- 웹뷰 기반 코드는 디버깅이 어려웠고, 웹과 네이티브 코드 간의 의사소통 문제로 새로운 기능을 추가할 때마다 충돌이 발생했습니다.
- 현대적 개발 환경에 적합하지 않았습니다.
- 최신 네이티브 SDK와의 통합이 제한적이었으며, 코드 재사용성이 낮아 개발 생산성이 떨어졌습니다.
이러한 문제는 사용자 경험에 직접적인 영향을 미쳤으며, 기존 구조를 근본적으로 개선할 필요성을 제기하게 되었고, 그 해결책으로 우리는 네이티브 전환이라는 기술적 결정을 내렸습니다.
아키텍처 구조 설계
네이티브 전환의 첫 번째 단계는 클린 아키텍처를 기반으로 한 구조 재설계였습니다.

기존 해외 숙소 모듈
기존 모듈 구조에는 아래의 단점이 존재했습니다.
- 하나의 해외 숙소 모듈에 패키지로 Domain / Data / Presentation Layer 가 분리되어 있어, 서로의 패키지에서 상호 참조가 가능했습니다.
- 기존에는, 공통으로 활용하는 하나의 DB 안에 해외 숙소 Table이 있는 형태라, 해외 숙소 관심사가 따로 분리되어 있지 않았습니다.
- 모든 레이어가 하나의 모듈 안에 존재 하기 때문에, Presentation 패키지만 수정되어도 모듈 전체가 재빌드됩니다.

수정 후 해외 숙소 모듈 의존성
위 문제점을 해결하기 위해, 클린 아키텍처를 기반으로 하여 모듈을 재설계 하였고, 각 관심사 별로 모듈을 분리하였습니다. 위와 같은 Entity 설계를 통해 서버와 앱 간의 데이터 변환 과정을 최적화하여, 안정적이고 유연한 데이터 처리를 가능하게 했습니다.
아키텍처 구조 적용 — local 모듈 분리
초기에는 앱 내 모든 테이블이 하나의 공통 데이터베이스에 포함된 구조를 사용했습니다. 이러한 방식은 초기 개발 단계에서는 간단하고 효율적일 수 있습니다. 그러나 해외 숙소 외 다른 기능과 데이터를 동일한 데이터베이스에서 관리하다 보니 비즈니스 로직을 파악하기 어려워져, 데이터베이스 분리가 필요하다고 판단되었습니다.
데이터 Migration 문제
모듈 분리를 위해 해외 숙소 테이블을 별도의 데이터베이스로 옮기는 작업이 필요했습니다. 동일한 DB 내에서 테이블을 이동하는 경우 Room의 AutoMigration 기능을 사용할 수 있지만, 다른 DB로 데이터를 옮기는 작업은 별도의 Migration 로직이 필요했습니다. 이를 해결하기 위해 다음과 같은 접근 방식을 도입했습니다

Migration 이후 앱 시작
StartUp 라이브러리를 활용
- 앱 초기 구동 시 이전 데이터베이스에 있는 데이터를 새로운 해외 숙소 데이터베이스로 Migration 하도록 구현했습니다. 이를 통해 기존 데이터 유실 없이 안전하게 이전할 수 있었습니다.
모듈화 일반화
- 해외 숙소 모듈 외에도 추후 다른 모듈 분리 작업에 활용할 수 있도록 Migration 로직과 기본 구조를 일반화했습니다.
이 과정을 통해 해외 숙소 Local 데이터의 독립성을 확보했으며, 데이터 관리와 유지보수가 보다 간단해졌습니다. 또한, 데이터베이스를 분리 함으로써, 비즈니스 로직을 좀 더 쉽게 읽을 수 있게 되었고 Migration 모듈 제작을 통해 추후 있을 Local DB 분리 작업을 좀 더 손쉽게 할 수 있게 되었습니다.
네이티브 전환기
앱 정책 동기화
- 여기어때 앱에서는 YDS(여기어때 디자인 시스템)를 적극적으로 활용 중에 있습니다. 웹에서 없던 디자인 시스템을 맞추기 위해, YDS를 활용하여 기존 앱의 디자인 시스템을 통합했습니다.
- Jetpack Compose 및 MVI 아키텍처를 준수하여 전체 코드를 재설계했습니다
비즈니스 정책 동기화
하지만 정책 담당자가 없는 경우도 있고 / 해당 정책이 왜 있는지 파악이 불가능 한 경우도 있었기 때문에, 웹뷰에 포함되어 있던 여러 정책과 동작을 그대로 가져오는 과정은 많은 커뮤니케이션이 필요했습니다.
- JSInterface로 앱과 웹뷰가 소통했던 정책을 적용하기 위해, 앱 ↔ 웹 소통하는 로직들을 모두 조사 하였습니다. 그 뒤, 더 이상 쓰이지 않는 JSInterface를 제거하고 해당 로직을 앱에 내재화하는 작업을 진행했습니다.
- 웹에 현재 적용된 정책들을 명확히 파악하기 어려웠습니다. 이에 따라, QA팀에서 이전 웹 검증 시 활용했던 Test Case 문서를 최대한 참고하여 과거 정책과 그 배경을 분석했습니다.
- 서버로부터 응답을 받을 때, Response 데이터의 규격이 웹과 앱에서 달랐습니다. 이로 인해 웹에서 사용 중인 모든 API에 대해 서버 담당자와 긴밀히 소통해야 했습니다. 앱에서 활용 가능한 형태로 Response 데이터를 수정 요청드렸으며, 이를 조율하기 위해 많은 커뮤니케이션이 필요했습니다.
이러한 과정을 통해 기존의 웹뷰 구조를 네이티브로 전환하면서도 최적화된 UI/UX를 제공할 수 있었습니다. 특히 네이티브 전환 후, 사용자 경험이 눈에 띄게 향상 된 것을 확인 할 수 있었습니다.
성능 측정 — Firebase Performance Monitoring
웹뷰에서 네이티브로 전환 후, 성능 개선을 확인하기 위해 Firebase Performance Monitoring을 사용하여 성능 데이터를 측정했습니다. 기존 사례를 참고하여 해외 숙소 홈에 적합한 측정 지표를 정의했습니다.
기존 해외 숙소 홈은, 웹뷰 기반 이기 때문에 WebActivity의 객체 생성 시점 ~ WebViewClient의 onPageFinished까지의 시간을 측정하였습니다.

Webview Load Trace
네이티브로 변경된 해외 숙소 홈은 Activity의 경우 해당 Activity 객체가 생성될 시점부터, Fragment는 onAttach 시점부터 뷰의 첫 번째 프레임이 그려졌을 시점까지의 시간을 측정하였습니다.

네이티브 View Load Trace
웹뷰 기반의 로드 속도와 네이티브 Compose 뷰의 로드 속도를 측정한 결과, 웹뷰에서는 약 2.61 초, 네이티브 기반에선 약 0.26초 가 소요되어 네이티브 전환 후 약 10배의 성능 개선을 확인할 수 있었습니다.

해외 숙소 홈 — 웹뷰

해외 숙소 홈 — 네이티브
이를 통해 네이티브 전환이 사용자 경험에 미치는 긍정적인 영향을 수치화할 수 있었으며, 성능 최적화 작업의 효율성을 검증할 수 있었습니다.
이번 클린 아키텍처 적용 및 네이티브 전환 과정은 기술적인 도전을 넘어, 서비스 안정성과 확장성을 확보하기 위한 중요한 여정이었습니다. 또한, Firebase Performance Monitoring을 활용해 정량적인 지표를 설정함으로써, 향후 리팩터링 후 성능 변화를 측정할 기준을 마련했습니다.
앞으로도 우리는 지속적인 기술 개선을 통해 더 나은 사용자 경험과 안정성을 제공할 수 있도록 노력하겠습니다.