정교한 노출 이벤트 적재를 위한 여정 Part 1 — XML 탐지하기

LeeWonJong
29CM TEAM
Published in
8 min readApr 16, 2024
generated by wrtn.ai

안녕하세요, 29CM Android 개발자 이원종입니다.

많은 서비스 회사에서 클릭율과 전환율을 중요한 지표로 분석하고 있는데요, 데이터팀이 의도한 방향으로 분석할 수 있도록 노출 이벤트를 요구사항에 맞게 정확하게 적재하는 것이 매우 중요합니다.

이에 대해 앞으로 세 편의 글을 통해 개선 과정을 소개드리려고 하는데요, 이번 글에서는 저희 팀이 노출 이벤트를 보다 더 정교하게 적재하기 위해 어떤 과정을 거치고 있는지 소개하려 합니다.

  • Part 1: XML 탐지하기
  • Part 2: Compose 탐지하기
  • Part 3: 이벤트의 중복과 예외로직, 보완로직 제어하기

배경

29CM 는 목적조직인 스쿼드와, 기능조직인 플랫폼 팀으로 나뉘어서 일을 하고 있습니다. 초기에는 전사 차원의 이벤트 적재 기준이 통일되지 않았기에, 스쿼드에서 자체적으로 이벤트명과 노출 기준 등이 약간씩 다른 문제가 있었던 상황이었습니다.

이에 데이터팀 주도로 클릭/노출 이벤트의 기준을 정의하게 되었고, 동시에 실시간 데이터 파이프라인을 자체적으로 새롭게 구축하게 되면서 기존 이벤트 적재 상황을 개선할 수 있는 기회가 있었습니다.

안드로이드 팀은 기존 이벤트를 앞선 글에서 소개드린 EventDispatcher 를 통해 적재하고 있었는데요, 전사 차원의 적재 기준이 통일된 만큼 기존 구조를 확장해야 할 필요가 있었습니다.

이벤트 적재 파이프라인 설계

먼저 저는 이벤트의 적재 파이프라인 구조를 다음과 같이 탐지(upstream) → 연산(operators) → 적재(downstream)와 같이 3단계로 나누었습니다.

  1. View 를 탐지합니다. 탐지된 View 는 정의된 threshold 에 따라 데이터를 반환합니다.
  2. 탐지한 데이터를 연산합니다. 하나의 화면에서 노출 및 반환되는 값은 중복될 수 있기 때문에 중복된 값을 제거합니다. 예외 케이스인 경우 이벤트를 적재하지 않을 수도 있고, 특정한 경우엔 반대로 보완적으로 이벤트를 추가 적재할 수도 있습니다.
  3. 최종적으로 연산된 값을 각 Analytics SDK 을 통해 적재합니다.

View 를 탐지하기에 앞서 29CM 에서는 XML, Epoxy, Compose 로 UI 를 구성하고 있는데요, Epoxy 는 Visibility-Events 를 제공하고 있어 노출이벤트를 적재하는데 어려움이 없었지만 저희는 Compose 로의 전환을 지향하기 때문에 기존 XML 로 만들어진 View 와 Compose 에서의 노출 이벤트 탐지를 추가로 개발해야 했습니다. 이번 글에서는 XML 에서 View 를 탐지하는 방법과, 그 과정에서 어떤 시행착오가 있었는지 설명드리고, 다음 글에서 Compose 에서 View 를 탐지하는 방법을 설명드리겠습니다.

XML 탐지

29CM 에서 주요 화면은 홈메인, 검색, LIKE 화면 등이 있고 각각의 화면들은 XML, Epoxy, Compose 등의 기술을 기반으로 다양한 UI 를 구성하고 있습니다.

홈메인은 Compose 전환 과도기여서 XML 을 아직 사용하고 있어 이 화면을 예시로 XML의 노출 이벤트 탐지 방법과 고려했던 사항들을 설명드리겠습니다.

아래 그림은 노출이벤트를 적재해야하는 화면의 레이아웃을 간략하게 그렸는데요, 붉은 박스는 배너와 피드의 영역을, 파란 박스는 상품 및 게이트 영역으로 이와 같이 Vertical 과 Horizontal 스크롤의 이벤트를 모두 적재할 수 있어야 했습니다.

홈메인을 포함하여 대부분의 XML 화면들은 RecylerView 를 사용하여 UI 를 그렸기에 빠른 적용과 기존 코드와의 의존성을 줄일 수 있도록 OnScrollListener 를 상속한 클래스로 해당 VisibleItemTracker 클래스를 만들었습니다.

OnScrollListener 를 상속한 VisibleItemTracker 는 onScrolled 에서 이미지와 같은 동작을 기대하도록 설계하고 구현하였습니다.

위와 같은 과정을 거친 후 Vertical RecyclerView 에 적용한다면 사용자가 스크롤 할 때 마다 붉은 박스의 배너와 피드를, Horizontal RecyclerView 에 적용한다면 파란 박스의 상품정보를 획득할 수 있었습니다. 또한 GridLayoutManager 가 LinearLayoutManager 를 상속하고 있었기 때문에 Grid 형태의 다른 상품 리스트 화면에서도 문제없이 노출된 아이템의 정보를 획득할 수 있었습니다.

해치웠나? 그럴리가..

최초 생각한 설계대로 해결되었다면 너무 좋았겠지만 늘 실제 개발에서는 예상치 못한 이슈가 발생하기 마련입니다 😅 구현하다 보니 대표적으로 아래와 같은 시행착오가 있었습니다.

1. 사용자가 스크롤 하지 않았을 때

사용자가 스크롤을 하지 않는다면 이벤트는 발생하지 않았습니다. 아래 사진의 경우 사용자가 위아래로 스크롤을 한다고 가정하면 캐러샐의 스크롤은 일어나지 않아 onScrolled 가 호출되지 않았고, 상품의 노출 이벤트는 적재되지 못했습니다.

그렇기 때문에 Vertical RecyclerView 의 EventItemTracker 에서 하위 캐러샐이 노출되는 시점에 해당 Horizontal RecyclerView 에 강제로 스크롤 이벤트를 발생시켜 해결했습니다.

view_event는 피드의 노출이벤트를 나타내고, view_event_product는 상품의 노출이벤트를 나타냅니다

2. 배너

배너는 일반 피드와 노출정책이 조금 달랐습니다. 이미지의 파란색영역이 화면에 노출되지만 이벤트를 적재하지 않고 붉은영역만 이벤트를 적재해야했기 때문입니다. 그러므로 배너는 VisibleItemTracker 를 사용하지 못하고 Idle 상태일 때에만 적재할 수 있도록 별도의 OnScrollListener 를 사용하였습니다.

3. 다이나믹 게이트

아래는 저희가 ‘다이나믹 게이트’라 부르는 홈메인 컴포넌트로, RecyclerView 를 사용하지 않고 HorizontalScrollView 기반으로 만들어진 커스텀 뷰입니다. 그래서 앞서 언급한 VisibleItemTracker 를 사용하지 못했고 대신 OnScrollChangeListener 을 활용해 동일한 탐지 로직을 구현하였습니다.

위 예시 말고도 시행착오들이 더 있었지만, Android 팀 내에서 다양한 컴포넌트의 노출 이벤트 대응을 지속적으로 논의하면서 설계를 발전시켜 나갔고, 결과적으로 데이터팀이 정확하게 원했던 형태로 정교하게 노출 이벤트를 적재할 수 있게 되었습니다 💪

마치며

이번 글에서는 29CM 에서 보다 더 정확한 클릭율과 전환율을 계산하기 위한 여정의 일부를 소개드렸습니다.

많은 서비스 회사에서 중요하게 생각하는 노출 이벤트는 어떻게 정책을 결정하느냐에 따라 구현 난이도와 방향이 많이 달라집니다. 이번 글에서는 그 첫 여정으로 XML 에서 View 를 탐지하는 방법과 저희 최초 범용으로 만들었던 Event Tracker 가 대응하지 못하는 엣지 케이스들을 소개드렸습니다.

앞으로 이어질 글에서는 Compose 에서 View 를 탐지하는 방법과, 탐지 후 이벤트를 적재할 때 29CM의 노출 정책을 어떻게 구현에 반영하였는지 소개드리도록 하겠습니다.

함께 성장할 동료를 찾습니다

29CM (무신사) 는 3년 연속 거래액 2배의 성장을 이루었습니다.

Android 팀은 Jetpack Compose 기반의 Declarative UI 로 개발을 해나가고 있으며, 효과적인 비동기 처리를 위해 Coroutine 과 Flow 를 활용하고 있습니다.

사업 영역에서는 콘텐츠, 검색, 액티베이션, 추천 등 여러 도메인에서 지속적인 실험을 통한 비즈니스 임팩트를 내는데 집중하고 있으며, 플랫폼 관점에서는 실시간 데이터 수집을 위한 인프라 개발, 앱 성능/에러 모니터링 고도화, 디자인 시스템 구축, 모듈화 아키텍쳐의 확장, QA 자동화 프로세스, 감도 높은 사용성을 위한 웹뷰 고도화, 디버깅 인프라 개선 등 여러 기술 과제들을 진행하고 있습니다.

위와 같이 여러 도전적인 과제들과 함께 고민을 나누고 같이 해결해 나갈 Android 엔지니어를 찾습니다.

저희 팀에 대해 궁금한 점이 있으시면 aosdev@29cm.com 으로 메일을 남겨주세요. 가벼운 온/오프라인 커피챗도 가능합니다!

저희 Android 포지션을 비롯해 많은 지원 부탁드립니다 :)

--

--