수익화 TF에서 사용자 경험을 개선하는 방법

안녕하세요, LINER의 프론트엔드 엔지니어 마크입니다.

LINER에서 수익화 TF에 참여한지 어느덧 반년이 다 되어가는데요. 수익화 TF는 LINER가 돈 걱정 없이 모든 것을 할 수 있게 만드는 것을 목표로 달려가고 있습니다. 현재는 유저들의 가입 후 30일 이내 구독 전환율을 올리는 것에 집중하고 있습니다. 목표를 달성하기 위해 온보딩에서 구독으로 이어지는 퍼널을 개선하거나, 유저들이 돈을 내고 쓸 만 한 가치가 있는 기능(ex. 파일 업로드 기능)을 새로 개발하는 등 여러 프로젝트를 진행하였습니다.

수익화 TF에서 만든 파일 업로드 기능

프론트엔드 개발자이기에 앞서, 수익화 TF의 일원으로서 어떻게 하면 더 많은 유저들이 구독을 할 수 있을까라는 고민을 많이 했는데요. 고민을 통해 얻은 배움은 크게 두 가지가 있었습니다.

먼저 구매 시 불필요한 허들을 줄여주는 것은 구독 전환율에 유의미한 영향을 준다는 것입니다. 체크아웃 모달을 보이지 않게 미리 띄워 로딩 속도를 단축시키거나, 확장 프로그램에서 웹을 거치지 않고 바로 결제로 이어지게 한 플로우를 구축함으로써 전환율을 높일 수 있었습니다.

또한 무료 체험이나 구독을 시키는 것도 중요하지만 멤버십이 적용된 유저에게 부정적인 사용자 경험을 주지 않는 것, 더 나아가 긍정적인 사용자 경험을 주는 것은 취소율을 줄이고, 전환율을 높이는 데 도움을 줍니다. 구독 후 열려있는 모든 탭에 멤버십 상태를 즉시 반영해 유저가 놀라지 않게 하는 것이 바로 그 예시입니다.

즉, 구독 과정에서의 사용자 경험을 개선하는 것은 구매 마찰 요소를 줄이고, 구독 후 유저들의 만족도를 높이는 데 도움을 주어 최종 지표인 구독 전환율을 높이는 데 도움이 됩니다. ‘체크아웃 로딩 속도 단축’, ‘확장 프로그램 바로 결제’, ‘구독 후 멤버십 즉시 반영’을 통해 프론트엔드 엔지니어로서 사용자 경험을 개선하면서도 구독 전환율을 어떻게 챙길 수 있었는지 소개하고자 합니다.

체크아웃 로딩 속도 단축

올해 2분기에 동료 알렉스가 체크아웃 로딩 속도에 대한 이슈를 제보해주셨습니다.

알렉스의 이슈 제보

무한 로딩은 고쳐야 하는 버그였지만, 체크아웃 모달 로딩이 오래 걸리는 이슈 또한 반드시 풀어야 하는 문제였습니다. 정량적인 데이터를 보았을 때 체크아웃 모달이 로딩되기 전 이탈하는 유저들이 존재해, 체크아웃 모달이 늦게 뜨는 것이 구매 마찰 요소라는 가설을 세울 수 있었습니다.

LINER는 결제 모듈로 Stripe를 사용합니다. Stripe를 이용한 체크아웃 모달을 띄우기 위해서는 선택한 구독 상품에 대한 clientSecret을 서버에서 가져와야 합니다. 당시는 체크아웃 모달 컴포넌트가 마운트된 이후에 서버에서 clientSecret을 받아오는 구조였기 때문에 모달이 열린 한참 뒤에도 로딩이 지속되는 문제가 있었습니다.

고민 중이던 저에게 CEO인 루크가 좋은 아이디어를 주셨는데요. 미리 유저가 선택 가능한 구독 상품들의 clientSecret을 서버에서 가져온 뒤 체크아웃 모달이 뜰 때 이를 사용하자는 아이디어였습니다. 더불어 체크아웃 모달까지 보이지 않게 미리 그려놓은 뒤, 유저가 구독 상품을 선택할 때 display 속성만 바꾸면 더욱 빠르게 로딩할 수 있지 않을까라는 제안도 해 주셨습니다.

페이지가 로딩되자마자 clientSecret를 미리 서버에서 불러오도록 처리했습니다. React Query 라이브러리의 useQueries라는 Hook을 사용해 여러 구독 상품들의 clientSecret을 클라이언트 캐시에 저장하였습니다. 불러온 clientSecret을 이용해 모달을 보이지 않게 렌더링하고 유저가 상품을 선택할 때 display 속성을 조절하여 바로 보여주도록 처리했습니다.

배포 이후 확실히 줄어든 체크아웃 로딩 속도

‘체크아웃 로딩 속도 단축’을 배포한 뒤, 약 6초가 걸렸던 평균 체크아웃 모달 로딩 속도가 약 2초까지 줄어들었고, 최종 구독 전환율도 상승했습니다. 작은 아이디어로 큰 임팩트를 낼 수 있다는 것을 배웠고, 구매 마찰 요소를 줄이는 것이 구독 전환율에 도움이 된다는 배움도 가져갈 수 있었습니다.

확장 프로그램 바로 결제

웹에서는 Stripe와 같은 결제 모듈을 사용할 수 있지만, 확장 프로그램의 경우에는 모든 웹 페이지 위에서 동작하므로 그렇지 않습니다. 유저들이 확장 프로그램이 그려준 구독 넛지를 누르더라도 바로 체크아웃 모달을 띄워주지 못하고, LINER 웹을 무조건 거친 후 띄워주어야 합니다. 유저는 웹 페이지가 로딩될 때까지 기다려야 하고, 구독 상품을 다시 선택해야 하며, 그 이후에 결제 정보를 입력해야 합니다. 결제까지 불필요한 퍼널을 최대한 줄이기 위해 수익화 TF에서는 ‘바로 결제’라는 이름의 프로젝트를 진행하였습니다.

프로젝트를 시작하기 전, 유저에게 어떤 경험을 줄 것인가에 대한 합의는 어느 정도 이루어졌지만 어떻게 구현을 해야 하는가에 대한 답은 나오지 않았습니다.

혹시 예전에 인터넷을 돌아다니면 종종 마주치던 팝업을 기억하시나요? 요즘은 브라우저에서 기본적으로 팝업을 차단하면서 많이 볼 수 없게 되었는데, 예전에는 많은 사이트들에서 팝업을 사용하였습니다. 저는 팝업의 인터페이스가 체크아웃 모달과 비슷하다는 점에 착안해, 확장 프로그램에서 팝업을 열 수 있는 방법에 대해서 찾아보았고 chrome.windows라는 API를 발견할 수 있었습니다.

확장 프로그램에서 윈도우에 접근할 수 있는 chrome.windows API

chrome.windows.create({ type: 'popup' })

위 코드를 사용하면 확장 프로그램에서 아래와 같이 탭과 메뉴가 없는 팝업을 열 수 있었고, 그 팝업에서 바로 Stripe 체크아웃 모달을 띄울 수 있었습니다. 간단하게 데모를 만들어 PO 헤일리, 디자이너 헤더와 소통하였고, 구현에 대한 합의를 한 뒤 프로젝트를 진행했습니다.

그 결과 ‘구독 넛지 클릭 → 페이지 로딩 대기 → 구독 상품 선택 → 체크아웃 모달 로딩 대기 → 결제 정보 입력’까지의 퍼널을 ‘구독 넛지 클릭 → 체크아웃 모달 로딩 대기 → 결제 정보 입력’으로 대폭 줄일 수 있었습니다.

바로 결제 팝업

프로젝트 배포 이후 확장 프로그램에서 기능 제한에 걸렸을 때 체크아웃까지 도달하는 유저의 수가 5배 정도 증가하였고, 무료 체험까지 신청하는 전환율도 마찬가지로 5배 상승하는 큰 성과를 낼 수 있었습니다. 구매 마찰 요소를 줄이는 것이 구독 전환율에 도움이 된다는 배움을 다시 한 번 얻을 수 있었습니다.

구독 후 멤버십 즉시 반영

구독 전환율을 높이기 위해서는 많은 유저들이 구독이나 무료 체험을 신청하는 것도 중요하지만, 중간에 취소하는 비율을 최소화해야 합니다.

수익화 TF PO 헤일리가 데이터를 살펴보았을 때, 유저들이 무료 체험을 한 뒤 아직 제한이 걸린 기능이나 구독 넛지를 보고 구독 페이지에 다시 들어오는 현상을 발견하였습니다. 그 중 일부는 무료 체험을 취소하였습니다.

실제로 유저가 업그레이드 한 탭에서는 구독 넛지가 사라지고, 기능 제한도 사라지지만 이미 열려있는 다른 탭에서는 새로고침을 하지 않는 이상 멤버십이 반영되지 않는 현상이 있었습니다. 구독은 했지만 반영되지 않는 것은 유저에게 부정적인 사용자 경험을 주었고, 구독 전환율에 부정적인 영향을 미쳤습니다.

다른 탭에 멤버십 상태를 어떻게 동기화시킬 수 있을까라는 의문에 가장 먼저 떠오른 방법은 React Query에 refetchOnWindowFocus 옵션을 활성화하는 것이었습니다. LINER 서비스 내 대부분 Query들은 다시 가져올 필요가 없어 staleTime: Infinite, refetchOnWindowFocus: false 옵션으로 설정되어 있었는데요. 멤버십 Query에 한해서만 refetchOnWindowFocus 옵션을 true로 두어 해당 탭에 포커스가 가게 되면 업그레이드 된 멤버십 상태를 가져오는 방법이었습니다.

가장 빠르고 쉬운 방법이었으나 문제가 있었습니다. 멤버십을 업그레이드하지 않은 경우에도 불필요한 콜을 계속 해야했고, 이전 멤버십 데이터에 의존하는 뷰들이 바로 사라지는 Side Effect가 있었습니다.

결제 성공 모달이 바로 닫히는 Side Effect 발생

이후 Broadcast Channel API에 대해서 알게 되었습니다. Broadcast Channel API는 동일한 origin을 가진 windows, tabs, frames에 대해 간단한 통신을 제공합니다. LINER 웹 서비스는 모두 동일한 origin을 가졌기에 적합한 방법이었고, 원하는 시점에 메시지를 보낼 수 있다는 점, 불필요한 API 콜을 하지 않아도 된다는 점이 매력적이었습니다.

같은 origin을 같인 context에서 통신할 수 있는 Broadcast Channel API

배포 이후 무료 체험이나 구독을 한 유저들이 구독 넛지나 기능 제한을 보는 일이 사라졌고, 같은 이유로 취소하는 유저들도 줄어들어 자연스레 구독 전환율이 상승했습니다. 프로젝트를 진행하면서 구독한 유저들의 사용자 경험을 개선하는 것도 구독 전환율에 도움이 된다는 배움을 얻었습니다.

마치며

LINER의 엔지니어들은 단순히 제품을 만드는 것을 넘어 비즈니스에 긍정적인 영향을 미치는 방법을 주도적으로 찾고 실행합니다. 이를 위해서는 목표에 대한 높은 이해와 공감이 뒷받침되어야 하는데요. LINER 팀은 구성원들이 방향성에 대해 충분히 이해하고 공감할 수 있도록 도와주는 문화를 중요시합니다.

프로젝트 킥오프 미팅부터 프로젝트의 목적에 대해 설명을 들을 수 있고, 자유롭게 질문할 수 있는 자리가 마련되어 있습니다. 구성원들이 목적을 보다 잘 이해함으로써 불필요한 요소는 덜어낼 수 있고, 가설을 증명하기에 충분하지 않은 부분이 있다면 보완할 수 있으며, 높은 동기를 가지며 진행할 수 있습니다. 목표에 대한 높은 이해와 공감이 여태까지 LINER 팀이 성과를 낼 수 있었던 이유라고 생각합니다.

함께 성장하고, 더 큰 임팩트를 내고 싶으시다면 언제든지 지원해주세요. 같이 일해요.