12/4일 원티드에서 진행한 <요즘 "프론트엔드 개발" 어떻게 하지?>라는 행사에 참관했다. 이렇게 평일에 진행하는 행사에 참여해보는것은 진짜 드문 것 같다. 사무실이 마포 합정에 위치해서 강남으로 오는게 엄청난 고역이라 매번 재밌어 보이는 행사도 그냥 생략해왔었는데, 요새 평상시보다 그래도 조금은 더 여유로워서 다녀올 수 있게 되었다.

이번 행사는 원티드에서 주최하고 세션들은 원티드, 우아한형제들, 토스 이렇게 세 기업에서 개발자 한명씩 진행을 했다. 그리고, 세션 전후로 각 기업의 개발팀들과 직접 얘기 할 수 있도록 각 기업들의 프론트엔드 개발팀도 따라왔었다.

사실 큰 기대 안하고 참여했었는데 굉장히 유익한 내용들이 많았다. 각 연사자 분들께서 돈 주고도 못 듣는, 그런 귀중한 경험들을 재미있게 공유해주셨다.

원티드 - useABTest(); A/B 테스트 라이브 코딩

image.png

이미지 출처: Google Optimize

A/B 테스트에 전반적인 소개를 해줬고 Google Optimize로 A/B 테스트를 하는 전체적인 흐름을 보여주었다. 원티드에서는 A/B 테스트를 통하여 회원가입률을 2배로 늘렸다고 했다.

그들이 테스트 했던 케이스는 다음과 같다.

A. 채용공고를 누르면 플로우를 막고, 바로 로그인/가입 유도

B. 채용공고를 누르면 공고 보여준 다음에 거기서 특별한 액션 (좋아요, 공유, 지원 등)이 발생하면 로그인/가입 유도

B 방식으로 하면 좋을 것 같다는 가설을 만든 후, 바로 기능 업데이트를 하는게 아니라 이 방식이 더 좋을 것이라는 것을 검증하기 위하여 A/B 테스트를 통하여 위 두가지 흐름을 신규 유저들에 대하여 동시에 진행을 했고 원하고자 하는 결과물을 얻었다고 한다.

A/B 테스트 라는 개념에 대하여 대부분의 국내 프론트엔드 개발자들이 익숙하긴 할 것 같은데 실행으로 옮긴 사람들은 그렇게 많지 않을 것 같았다. (이건 온전히 내 주관적인 생각이다. 왜냐하면 나의 경우 회사에서 자주 언급해왔어도 A/B 테스트를 할 수 있는 환경을 구축하기 귀찮아서 실제로 실행으로 옮긴건 1~2년 뒤였다) A/B 테스트를 안해본 사람들에게 이에 대한 감을 잡기 위해서 큰 도움을 줄 수 있었던 세션인 것 같다.

A/B 테스트를 라이브 코딩으로 보여줬는데, 처음엔 이렇게 제한된 시간인데 어떻게 하시려고 하지? 의문이 들었지만 그냥 간단한것들 하나하나 소개 하고, 미리 이것저것 세팅해 둔 다음에 한 2~30줄 정도의 코드로 시연을 해주었다.

조금 아쉬웠던 부분은 Google Optimize 에서 테스트를 하고 나서 각 테스트에 대한 지표를 보여주는 페이지를 보여줬으면 청자들의 끄덕끄덕-factor를 이루어 낼 수 있었을 것 같은데 그 부분에 대한 건 그냥 말로만 설명해주었다.

그리고 원티드에서는 Next.js 를 사용해서 서버사이드 렌더링을 한다고 했다. 그래서, 세션이 끝나고 Q&A 때 서버사이드 렌더링 할 때 A/B 테스트는 어떻게 하시냐고 여쭤봤는데, 답변을 해주기시긴 했는데 딱히.. 나의 궁금증이 해결 되지는 않았다. 아무래도 원티드에서 진행 한 테스트들은 주로 사용자의 액션이 트리거 될 때만 분기점을 만들어서 큰 문제점은 없었던 것 같다.

만약 사용자의 액션에 의하여 분기점이 발생하는 것이 아니라 사용자의 첫 방문부터 A/B 테스트가 시작되는 것이라면, hydrate를 하는 과정에서 문제가 발생한다. 가령 A 에겐 "안녕하세요" B 에겐 "반갑습니다" 라는 문구를 보여줬다고 가정해보자.

서버사이드 렌더링 시 발생할 수 있는 문제점은 hydrate 하는 과정에서 좀 이상하게 작동 할 수 있다는 것이다. Google Optimize 에서 알려주는 일반적인 사용법으로는 useEffect 또는 componentDidMount에 해당하는 부분에서 Google Optimize 의 API를 호출하여 테스트를 시작하고, 또 이 과정에서 사용자의 타겟 그룹이 정해진다. 하지만 서버사이드 렌더링을 한다면, 서버측에서는 useEffect 및 componentDidMount는 호출이 되지 않기 때문에 사용자에게 A 로 보여줘야 할 지 B 로 보여줘야 할 지 모른다. 가령, 서버사이드 렌더링 시에는 무조건 A로 보여주기로 결정했다면 페이지 로딩하는 과정에서 자바스크립트가 모두 로딩될 때 까지는 A로 보여지다가, Google Optimize 를 통하여 타겟 그룹이 정해진 뒤 B로 다시 렌더링 되어버릴 수 있다. 따라서 서버사이드 렌더링을 한다면 일반적인 방식으로 처리 할 수 없다.

이전에 이와 비슷한 상황을 겪었어서, 서버사이드 렌더링 시에는 그냥 A/B 테스트를 하는 경우 해당 부분을 렌더링 하지 않았다가 클라이언트쪽에서만 렌더링을 하도록 결정한적이 있었는데 이 방식이 나는 마음에 들지 않았다. 오늘 아침에 조금 알아보니까 Google Optimize 에서 Server-side Experiments 라는 문서가 있었다.

사실 이전에도 봤었던 것 같기도 한데 PHP여서 그냥 넘겨버렸었다. 그런데 지금 다시 읽으니 어떻게 해야 할 지 조금은 감이 잡힌다. 일단 이 문서는 서버사이드 렌더링과는 관계 없이 그냥 서버에서 분기를 나누는 방식에 대하여 다룬다.

<?php
// Sets the ID of the experiment on variations of this web page.
$experimentId = '16iQisXuS1qwXDixwB-EWgQ';

// Randomly picks a variation for the user.
$variationId = rand(0, 2);
?>

그냥 A로 할지 B로 할지 정하는것을 Google API를 호출해서 정하는게 아니라 서버측에서 랜덤 함수 돌려서 정하고 이를 다음과 같은 형식으로 클라이언트까지 전달을 해주면 된다고 한다.

<?php
<<<HTML
  // 3. Set the experiment ID and variation ID.
  ga('set', 'exp', '$experimentId.$variationId');
HTML;
?>

그럼, 이것을 리액트ish 하게 생각해보자면 우선 A/B Test를 위한 Context를 만들어야 할 것 같다. 그 다음에는 어떤 Hook 을 만들어서 a 할지 b 할지 정해준 다음에 그 결과를 특정 상태에 담아두고, 이에 따라 렌더링도 해야겠다.

그런데 또 이것으로 끝이 아닌게 만약에 SSR 결과를 캐싱한다면 또 어려운 난관이 시작된다. 보통 SSR 캐싱을 할 때 로그인 유무, 주소를 기준으로 캐싱을 하게 되는데 A/B 테스트를 하면서 캐싱도 하고 싶다면 결국 분기점을 나누는 부분을 리액트 렌더링 바깥에서 해주어야 된다. 오우 헬게이트! 생각해보니까 과거에 또 이런 문제점 때문에 클라이언트에서만 A/B 테스트 하도록 처리했었던 것 같다.

A/B 테스트를 도입하는 것 자체는 쉬울 수 있지만, SSR을 한다면 큰 삽질이 발생하게 된다. 이 문제점을 제대로 해결하려면 마음 먹고 며칠간 삽질해야만 원하는 결과가 나올 것 같다.

우아한형제들 - 디자인 시스템으로 가는 길

우아한형제들의 김민태님께서는 배달의 민족 프로덕트에 디자인 시스템을 적용하는 과정에 대해서 이야기를 나누어주셨다.

우선 우아한형제들에서 발생한 문제점에 대해서 설명해주셨다. 우아한형제들에서 프로덕트 개발에 들어가는 인원은 거의 400여명 이라고 한다. 그리고 사내에서 진행하는 크고 작은 프로젝트의 수가 정말 많다고 한다. 우아한 형제들에서 디자인 시스템 도입을 하기로 한 이유는 여러가지가 있었다.

첫번째로는, 배달의 민족 서비스 내에 생긴건 비슷하지만 디자인/개발은 따로따로 진행된 UI가 꽤나 많다고 한다. 생긴건 거의 비슷하지만 기능이 조금씩 다르고, 그리고 조직이 크기 때문에 만드는 사람들도 다르고 해서 비효율이 발생했다고 한다.

두번째로는, 이 부분을 좀 더 강조해주셨었는데 우아한형제들에서는 더 많은 것들을 더 빠르게 진행을 하고 싶었는데 개발 프로세스에서 디자인 QA 과정이 병목이 될 때가 자주 있었다고 한다. 개발 다 끝났는데, 디자인 QA 에서 뭐가 잘못되서 다시 기획단계로 돌아가는일 이 발생한다던지.. 그래서 우아한형제들의 선택은 꽤나 과감했는데, 디자인 시스템을 적용하면 디자인 QA 과정을 없앨 수 있을 것이다! 라는 가설을 내렸다고 한다.

과연 디자인 시스템을 적용한다고 해서 디자인 QA를 생략할 수 있을까? 분명히 디자인 시스템으로 커버하지 못하는 UI 가 분명히 있을텐데 말이다. 그런데 확실히 디자인 QA 작업이 매우 간소화 될 수 있을 것이란 생각이 들긴한다. 배달의 민족에서는 앱 내의 90% 의 UI 는 디자인 시스템으로 커버 할 수 있을 것이라고 생각한다고 말씀해주셨다.

세번째로는, 사용자의 방문율이 높은 화면은 자주 개선되는 방면 방문율이 낮은 화면은 개선이 매우 뜸하게 진행되어 조화가 이뤄이지지 않을 수 있다는 것이다. 이 때 배달의민족의 결제하는 화면과 배달의 민족의 프로필 설정 화면을 비교하면서 설명을 주셨다. 결제하는 화면은 요즘 트렌드에 맞게 디자인이 깔끔하게 되어있었고 설정 페이지는 조금 뒤쳐져 있었는데 큰 차이를 못 느낀다면 백엔드 개발자 해야 된다고 하셨다. (차이는 있었는데 설정 페이지가 내가 느끼기엔 그렇게 구리진 않았다...)

우아한형제들에서는 디자인 시스템을 도입하기 위해서 약 2년의 시간이 걸렸다고 한다. 디자인 시스템 개발만 2년이 걸린것은 아니였다. 우선 사내 디자이너들을 설득해야 됐었고 설득하기 위하여 교육을 많이 했다고 한다. 디자인 시스템을 만드려면 디자이너가 코드에 익숙해져야 됐기 때문에 내부에서 Framer 스터디도 하고.. 그리고 프로토타입도 만들어보고... 실무 프로젝트에 적용 후 배포까지 2년이 걸렸다고 한다.

디자인 시스템을 만들기 위해서 사용된 기술 스택들을 간략하게 소개해주긴 했는데 완전 자세히 해주신 것은 아니라 어느정도 짐작 할 수만 있었다. 우아한형제들에선 Sketchapp을 사용하여 디자인을 하는데, airbnb에서 만든 도구 중에서 코드를 작성해서 UI를 만들 수 있게 해주는 걸 사용한다고 했다. 아마 이걸 언급 하신 것 같다. react-sketchapp 이라는 Sketchapp 플러그인인데 마우스로 직접 하나하나 입력하는게 아니라 리액트 컴포넌트를 작성해서 Sketchapp에 보여주게 하는 방식이다.

Sketchapp은 버전 43부터 파일을 저장 할 때 Binary가 아닌 JSON 형태로 저장한다고 하는데 우아한형제들에서는 이러한 시스템을 유용하게 사용하고 있다고 한다. (정확히 어떤 식으로 사용하는지는 잘 모르겠다..!) "Meta Lang" 이라고 언급하는 무언가를 만들었는데 여기서 디자인에서 사용되는 모든 값들을 JSON으로 관리하고, 여기서 디자이너가 값을 수정하면 바로 Sketchapp에 반영된다고 한다.

Sketchapp으로 만들고 나면 이를 기반으로 컴포넌트 라이브러리를 만든다고 한다. 라이브러리를 만들고 나면 이를 npm에 등록하고, 디자이너들이 Framer X 에서 npm에서 라이브러리를 땡겨와서 그걸 가지고 UI를 만들어낸다고 한다. Framer X에서 컴포넌트들을 쉽게 내보내고 다른사람이 만든 것도 불러와서 사용하고 그럴 수 있는건 알았는데 npm에서도 불러올 수 있는 줄은 몰랐다. 매우 놀라운 것 같다. 관련 내용은 여기에서 알아 볼 수 있다.

김민태님께선 디자인 시스템은 디자인 팀에서 주도하고 엔지니어 팀에서 서포트 하는 것이라고 말씀하셨다.

나는 조직이 크면 디자인 시스템을 도입하는 것이 오히려 더 쉬울 줄 알았다. 하지만 결코 그렇지 않았다. 조직이 만약에 작다면 프로덕트 개발 흐름을 실험적으로 바꿔서 쉽게 진행해볼 수도 있지만 조직이 크다면, 조직 내에 쪼개져있는 수많은 팀들이 새로운 방식을 도입해야 되기 때문에 Workflow를 제대로 설계하고, 더욱 세밀하게 점검 할 필요성이 크다.

토스 - 토스의 프론트를 지탱하는 마이크로서비스 아키텍처와 자동화

마지막 세션에선 토스의 박서진님께서 진행해주셨다. 이 세션에서는 토스의 프론트엔드 개발팀이 어떻게 일하는지 전반적인 소개를 해주었다.

세션의 도입부분에서 토스에서는 애자일 문화를 매우 중요시 여긴다고 한다. 빠르고 잦은 실험을 하고 작은 실패를 하는 것이 중요하다고 했다. 개발 사이클이 일주일만에 끝날때가 있다고 한다. 즉, 월요일에 가설을 세우고 금요일에 릴리즈까지 마친다는 것. 음, 참 대단하구만.

애자일 방법론을 매우 중요시 여겨서 새로운 입사자에게 관련 서적을 꼭 읽으라고 준다던데.. 책 제목이 뭐였는진 기억나질 않는다. 나도 한번 읽어봐야겠다. 애자일 방법론에 대해서는 블로그 포스트만 몇번 읽어본게 다인데. 있다가 토스 개발자님한테 직접 여쭤봐야지.

수정: 그 책은 린 스타트업이라는 책이다. 어떤 내용인지 궁금해서 방금 주문했다! ㅋㅋ

토스의 모바일 앱 안에 있는 수많은 기능들은 네이티브 코드를 사용해서 개발 하지 않고 웹 기술을 사용하여 개발한 다음에 웹뷰를 통하여 보여주었다고 한다. 이는 이전에도 알고 있긴 했었는데 이 세션을 통하여 정확히 왜, 그리고 어떻게 작업을 하고 있는지 알 수 있었다.

토스에선 기능 업데이트를 자주하는데, 여기서 독이 되는것이 바로 앱 심사 및 릴리즈라고 한다. 웹 기술을 사용함으로써 심사 딜레이를 겪지 않고, 모든 사용자가 최신 버전을 사용 할 수 있게 하는것이 가능해졌다고 한다. 이 부분은 꽤나 공감됐다 특히 Apple App Store의 심사가 진짜 까다롭고 오래걸리니까...

애자일하게 작업하기 위하여 앱 안의 다양한 서비스를 모바일 웹으로 구현했다고 한다.

그리고, 토스의 프론트엔드는 처음 모놀리식(monolithic) 아키텍처를 사용했다고 한다.

image.png

토스에서는 프로덕트를 기준으로 팀을 나눠서 운영하는데 이를 사일로(Silo) 라고 부른다고 한다. 관련해서 자세한 내용은 여기에서 볼 수 있다. 지금은 프론트엔드 개발자가 9명이고 곧 10명이 된다고 한다. 현재 개발자 한명이 서비스 하나씩 책임지고 있고, 각 개발자가 자기가 맡은 프로덕트에 대한 완전한 권한과 책임이 있다고 한다.

그리고 프론트엔드 개발자들 전체를 챕터(Chapter) 라고 부른다고 한다. Spotify 의 조직 모델과 꽤나 유사한 것 같다.

모놀리식 아키텍처를 사용하면서 겪은 가장 큰 문제점은 프로덕트의 덩치가 커감에 따라 배포하는 시간이 길어진 것이라고 한다. 한번 배포하려고 할 때마다 20~30분 정도 걸렸다고 하는데.. 세션의 도입부에서 언급했던 것 처럼 토스에서는 애자일을 중요시 여기기 때문에 업데이트를 자주 해야하는데 배포 시간이 너무 오래 걸리는 것은 해롭기 때문에 마이크로서비스 아키텍처를 고려했다고 한다.

처음엔 프로젝트를 마이크로서비스 아키텍처로 분리하고, 각 프로젝트의 Git 레포를 따로따로 운영을 했는데 이로 인하여 재사용 되는 코드를 공유하기 힘들어졌고 또 코드들을 트래킹하기 어려워졌다고 한다. 또한, 라이브러리 버전도 제각각이라 관리하기 힘들어졌다고 했다. 그래서, 모노레포 도입을 시도했고 이를 성공적으로 끝냈다고 한다.

모노레포는 라이브러리들과 서비스로 구성이 되어있는데 한 줄 명령어로 새 라이브러리 또는 서비스를 만들 수 있도록 자동화를 해놓았다.

토스는 gocd 를 사용하여 배포를 자동화했다고 하며, 카나리 배포 전략을 사용한다고 한다. 카나리 배포 전략은 소프트웨어를 릴리즈 할 때 전체 사용자에게 바로 릴리즈 하는 것이 아니라 일부 사용자한테만 릴리즈를 하고 모니터링(토스에서는 Grafana를 사용해서 모니터링을 한다)을 한 다음에 특별한 문제가 없으면 전체 사용자에게 릴리즈 하는 방식을 말한다. 토스에선 로드 밸런서 설정을 통하여 카나리 배포를 했다고 한다.

사실 나는 웹에서 카나리 배포 전략을 사용 할 생각은 한번도 안해봤는데, 음... 다음번에는 한번 고려해봐야겠다.

그리고 현재 Netlify로 Deploy Preview를 도입하기 위한 작업을 준비중이라고 한다.

토스의 세션이 끝난 다음에 내가 토스는 각 프로덕트 별로 사일로가 나뉘어져있는데 그럼 마이크로서비스 아키텍처의 전환, 모노리포 전환, 자동화 이런건 누가 진행하냐고 물어봤었는데 대부분 진행자 본인 (박서진님)이 진행을 했으며 이 작업을 할 때에는 잠깐 본인이 맡고 있던 프로덕트에서 잠깐 나왔었다고 한다.

세션이 끝나고..

세션이 모두 끝나고 나서는 패널 토크가 있었다. 패널 토크때도 유용한 내용이 많았는데, 내가 원래 이 참관 후기를 당일 밤에 쓸 줄 알고 따로 적어두지는 않았어서 어떤 내용이 오고 갔는지 대부분 기억에서 잊혀졌다..!

패널 토크 다음에는 네트워킹 시간이 있었는데 마침 토스의 이현섭 개발자님도 오셔서 수다 조금 떠니까 끝나버렸다 ㅋㅋㅋ 아 그리고 이름도 말하지 않았는데 나를 알아보신 분이 몇 분 계셨다. 신기했다.

원래 나는 사무실이 멀어서 강남에서 평일에 진행하는 행사는 재밌어 보이는 것도 거의 불참했었다. 사실 사무실이 먼 것도 있지만 너무 바쁘게 살았어서 매번 생략해왔었는데, 이런 행사에 청중으로 참여하는 것도 꽤나 재미있는 것 같다. 내년엔 좀 더 자주 참여해야겠다.

이번 행사에서 각 기업들이 어떻게 일하는지 들으면서 어떻게 하면 내가 속한 팀의 개발 문화를 더욱 개선 시킬 수 있을 지에 대한 고민을 해볼 수 있는 계기가 되어서 참 유익했다.

아, 기업 굿즈를 이것 저것 많이 챙겨왔는데 재밌다.

  • 원티드: 나무로 만든 필통! 그 안에 연필이랑 지우게 들어있음, 에코백 - 질문했더니 줬음, 작은 연습장 3개
  • 토스: FRONT END 라고 적혀있는 파란색 모자. 칫솔! 아니 토스 칫솔은 대체뭐지 ㅋㅋㅋ 쌩뚱맞아서 꿀잼, 토스 스티커.