원티드 AB테스트
원티드는 가설
테스트
검증
3가지 단계로 프로덕트를 개선한다.
가설이라는건 사람마다 다르게 생각하고 결과 예측도 사람마다 다 다르게 한다. 남을 설득하거나 설득 당할수 있다. 경험이나 감만으로 결과를 예측하는것은 위험하다.
테스트 단계에서 프론트엔드 개발팀이 기여했던 경험에 대해서 얘기해보겠다.
회원가입전환룰 높이기위해 진행한 ab테스트
채용공고 신규 유저 화원가입 전환률 높이기
- 채용공고를 보기전 회원가입 유도 (a)
- 채용공고는 보여주고 추가적인 액션시 유도 (b)
1번 - 메인화면의 잡카드를 클릭시 상세로 넘어가지 않고 로그인창 띄우기
2번 - 상세에서 채용공고는 보여주고 공유하기
, 지원하기
버튼 클릭과 같은 적극적인 액션시 로그인창 띄우기
결과를 먼저 얘기하면, AB테스트로 회원가입 전환률 2.5배 상승 효과가 있었다. 테스트 하기전엔 두가지 안 모두 그럴듯해보였지만, 테스트 후 큰 결과의 차이를 가져왔다.
구글의 gtag라는 라이브러리 사용(유료)하여 컴포넌트가 마운트 되었을때 콜백함수에서 실험의 번호와 이름을 인자로 받아서 각 실험에 대한 분기처리를 해줄 수 있다. 실험 페이지에 접속한 유저중 몇퍼센트 유저에게만 실험을 진행할건지 각 대안 AB의 가중치는 어떻게 할건지 등을 정할 수 있다. 어떤 페이지를 실험할건지도 정할 수 있다. 개발자의 적극적인 노력이 실제로 사업에 도움이 된 겅우를 원티드의 사례였다.
개발을 가장 중요시하지만 UI/UX, 테스트, 제품개선의지 등도 중요시해야 좋은 제품을 만들 수 있다
라이브코딩
위 사진은 현장에서 진행된 라이브 코딩 예시용 프로젝트이다.
사이트에 접속한 유저중,
A테스트 유저
에겐 최우식 사진을 보여주고
B테스트 유저
에겐 펭수 사진을 보여준다.
어떤 사진이 더 유저의 반응을 이끌어낼 수 있을지 테스트 하기 위한 예시
원티드의 기술 스택
- 전부 리액트로 구성 공통 요소는
리액트 리덕스 웹팩
이다 - ssr(
서버사이드렌더링
)을 위해넥스트
사용 - 일부에서
타입스크립트
점진 도입중,RxJs
는 레거시
사스를 기본적으로 사용하되, 동적 데이터 처리에는 스타일드 컴포넌트
를 사용한다. 지라
를 통해서 이슈 관리 한다.
티켓 담당자 할당 → 깃 브랜치 생성 → 작업 완료 → Pull Request → Develop branch merge → CI/CD를 통한 EC2 자동 배포 (번역파일
및 static resources
는 s3사용)
Pull Request를 통해서 코드리뷰를 진행하고, 기존 소스 영향도 체크 및 잠재적 버그를 예측한다.
원티드는 총 4개의 도메인을 사용하는데 각 영역의 기술스택이 통일되어있지 않지만, 점진적으로 개선해나가는 중이고 스택 통일로인한 도메인 스윗칭 비용 감소 효과를 기대중이다.
Q&A
Q. 서버사이드렌더링시 ab테스트 어떻게 진행해야 하는가?
질문 상세 : 유저의 액션이 있을때 테스트하는게 아니라 페이지에 처음 접속했을때 UI 배치를 변경해서 어떤 UI가 더 좋은지 테스트를 하기 위해서는 서버사이드렌더링시 AB테스트를 적용해야 할거같은데 그럴땐 어떻게 해야 하는가?
A.
아직까지는 그런 테스트가 필요하지 않았다. 지금까지는 유저의 액션에 따라서 테스트를 진행하는 경우만 있었어서 컴포넌트가 마운트 된 다음에 테스트를 해왔다.
Q. 테스트 코드가 길어지면 그 코드에 대한 관리는 어떻게 하고 있는가?
A.
지라 티켓과 커밋을 별도로 생성해서 한번에 revert하면 좋겠지만 그렇지 못한 경우가 많아서 별도로 제거 티켓을 받아서 한번에 몰아서 진행하는 편이다.
테스트 코드는 우선 두개의 안 중 더 괜찮은 안을 먼저 구현한다음에 완성되고 나서 테스트 코드를 작성하고 있다. 기획단계에서부터 AB테스트 도입에 대한 고려를 한다.
테스는 보통 2~3주 혹은 두세달정도 걸린다.
이 api는 유료이다. 가격은 잘 모르겠다. 일정 사용량까지 무료
배달의 민족 : 디자인 시스템
발표자 : 우아한형제들 김민태
프론트엔드 개발자의 일하는 방식에있어 우형은 어떤 시도들을 하고있나에 대해서 얘기해보겠다.
준비를 거의 이년동안했고 두세달전부터 디자인 시스템 프로덕션 릴리즈 준비중이다.
일반적인 개발 워크 플로우
기획
디자인
프론트개발 백엔드개발
기능QA 디자인QA
릴리즈
위처럼 반복되는 워크플로우들을 디자인 시스템으로 개선 해보자.
개선을 하게 된 배경에는 두가지 이유가 있다.
1. 반복되는 롤백
디자이너의 의도를 프론트 개발자가 잘 파악하지 못해서 실제 결과와 디자인 사이의 조금씩 차이가 생긴다. 이런일이 생기는 이유는 디자이너는 비트맵을 생산하기 때문에 실제 워킹되는 상황에서의 다양한 상황을 상상하기 힘들기 떄문이다.
또한, 어떤 부분을 중요하게 생각하는가에 대한 개발자와 디자이너의 차이 때문에 디자인결과와 실제 코딩된 결과가 차이가 있을 수 밖에없다.
어떤경우엔, 디자이너가 실제로 돌아가는 화면을 보니 마음에 안들어서 다시 디자인 재검토 혹은 심지어 기획 재검토까지 하는 일이 다반사이다. 이런 경우에 서로 더 나은 대안이 있다는걸 알지만 오픈 일정 압박때문에 우선 배포를 하고 나중엔 잘하자고 결심하지만 또 같은 일이 반복된다.
기획
디자인
프론트개발 백엔드개발
기능QA 디자인QA
릴리즈
이 단계에서, 디자인QA단계를 없애기만해도 이 프로세스에 굉장히 큰 효율성을 가져다 줄 수 있다.
디자이너가 디자인 할떄부터 실제 코드로 작동하는 컴포넌트를 가지고 하기떄문에 다시 롤백되는 일이 현저히 줄어들어든다.
2. 컴포넌트 라이프 사이클 문제
미세 하게 달라진 컴포넌트
문서는 쓰는 순간부터 낡는다는 말이 있다. 이처럼 큰 규모의 앱도 마찬가지이다. 유저가 자주 많이 사용하는 페이지는 계속해서 개선되지만 그렇지 못한 페이지는 예전 그대로 낡아간다.
예를 들어 배민에서 프로필 수정 화면은 다른 화면들에 비해서 계속 낡아가고있다.
각 영역에 같은 컴포넌트가 들어가는데, 이 컴포넌트가 영역마다 미세하게 달라지는 일이 생겼다. 이걸 수동으로 관리하다보니 관리가 매우 어려웠다. 각 영역마다 디자이너, 개발자, 기획자가 모두 다르다 보니 생긴 문제였다. 프론트엔드 팀에게 이 문제를 해결하라는 지시가 떨어졌다.
페이지의 룩을 바꾸기 위해선 생각보다 큰 코스트가 발생한다. 로직 자체는 그대로 사용한다고 해도 그렇다. 디자이너는 몇번 없을 개편에 최대한 많은것을 넣고 싶어하고 욕심이 있어서 스펙이 커진다.
디자인 시스템 해외 사례
에어비엔비
- 굉장히 잘 되어있고, 도구들이 오픈소스로 잘 공유되어있다. 선구자로서 어떤걸 해야하고 어떤 장벽이 있는지 잘 정리 되어 있어서, 우리도 레퍼런스로 삼아서 보고 있다.
Material Design
Spotify
해외사례를 그대로 우리 회사에 적용하는거 자체가 하드한 일이고, 성공한다는 보장도 없다. 회사마다 사정이 다르기 때문이다.
디자인 시스템의 필요성에 대해서 모두의 합의를 이끌어내는 과정도 힘들었다.
사내 프레이머X 교육, 프로토타입작성 등을 통해 공감대를 어느정도 이끌어 낸뒤, 시작할 수 있었다.
디자인 시스템은 적용을 위해 2~3년이 걸리며 조직의 전폭적인 지원이 있어야하고 실패하기 쉬운 개발 외적인 이슈들이 굉장히 많다. 그래서 우리는 점진적으로 도입하고 있다.
배민의 디자인 시스템 구조
- 디자이너가 디자인하는 순간 실제 컴포넌트를 기반으로 디자인한다.
- 스케치로 디자인을 하고 코드로 내보낼 수 있다.( 내보내면 디자인 시스템의 일부가 되는거같음 ) 디자이너는 디자인 코드로 보고 개발자는 개발자 코드로 보기 위해 중간에
Meta Lang
이라는것을 넣었다. - 에어비엔비의 SDK를 스케치에서 사용해서 디자인 시스템에 있는 컴포넌트들을 스케치에서 브라우징 해볼수도 있다. (디자인 시스템과 스케치앱 사이 변환)
Meta Lang
→리액트 컴포넌트
자동 변환은 아직 구현하지 못했다. 지금은 팀을 만들어서 수동으로 하고 있다.- 변환을 한뒤에
NPM Private Repository
에 퍼블리싱 해두면프레이머X
,스토리북
,APP
등에서import
해서 데이터를 입히는등 사용한다. - 스케치만 가지고선, 실제 환경에서 돌아가는 디자인 상태를 볼 수 없어서
스토리북
으로 퍼블리싱해서 실제 환경에서 볼 수 있도록 구성했다.
스케치가 디자인에서 대세가 되면서, 원래는 바이너리 파일로 내보내졌던것들이 JSON
포맷으로 변경되었다. 그떄부터 스케치에 여러가지 플러그인들이 생겨서 Meta Lang
을 만들어서 이런 디자인 시스템을 구성할 수 있었다.
스케치의 포맷이 JSON으로 변경된것이 굉장히 큰 변화였다.
요약
디자인
→ JSON으로 내보내기
→ Meta Lang
→ 리액트 코드
로 변경.
이런 과정을 자동화 함으로써, 위에서 말한 두가지 문제를 해결해 나가고 있다.
디자인 시스템에서의 디자인 컴포넌트가 변경되면 위 과정을 거쳐 import시 새롭게 업데이트된 컴포넌트가 자동으로 리액트 컴포넌트도 업데이트 되기 때문이다.
디자인 팀에서도 디자인 시스템으로 만들어진 컴포넌트가 60%정도 되었다. 40%만 하면 되겠네라고 생각하겠지만 만들다보니 Presentational Compoent
가 아니라 Container Component
로 빼야하네? 와 같은 일들이 자주 발생했다.
토스 : 마이크로프론트엔드 아키텍쳐와 자동화
토스 박서진 개발자
가설
개발
배포
- 애자일 방법론 사용.
유저는 데이터를 기반으로만 이해할 수 있다.
최대한 빨리 개발해서 빠르고 잦은 실험과 작은 실패를 장려하는것이 좋다.
네이티브 개발로는 어려움이 많다.
네이티브는 개발을 한다음에 앱 번들을 빌드하고 앱스토어에 심사를 올려야한다. 배포된 이후에도 많은 사용자들이 앱을 업데이트할때까지 기다려야한다. 이런점은 애자일 방법론과는 잘 맞지 않는다. 잦은 실험과 작은 실패를 해야하는데, 네이티브 개발은 애자일 방법론에 조금 방해되는 요소가 있었다.
사용자의 반응을 빠르게 확인해서 빠르게 제품을 개선해야했다.
그래서 앱안에서 웹뷰로 빠르게 서비스를 개발해 나갔다. 네이티브보다 성능적으로 손해를 보더라도 위 요소들이 더 중요하다고 생각했다. 리액트와 타입스크립트를 기반으로 앱내 웹앱을 개발해 나가고 있다. 토스에서 30개가 넘는 서비스들이 네이트브안에서 웹앱으로 돌아가고 있다.
많은 서비스들을 관리하는 방법은 두가지가 있다.
1. 모놀리식 아키텍쳐
"단단히짜여 하나로되어있는"이라는 뜻이다. 하나의 패키지안에 여러 서비스가 있는 자연스러운 구조이다.
장점
하나의 큰 리액트 프로젝트 안에 행운서비스
, 비대면계좌개설
등이 서비스폴더
로 구분되어있다. 소스들을 공통화 하거나 라이브러리들의 버전관리가 굉장히 간편했다. 템플릿을 만들때도 스캐폴딩
을 통해 손쉽게 새로운 서비스를 구축할수 있었다. 관리비용이 절감되었다.
단점
가장 큰 단점은, 빌드 시간이 굉장히 오래걸린다.
빌드시간이 코드가 늘어감에 따라 20분
이상이 걸리기도 했다. 배포한번이 굉장히 힘들었다.
- 공통화가 많이 되어 있기 때문에 하나의 변경사항이 다른 서비스에 영향을 미칠 수 있다.
- 서비스 별로 별도 배포가 불가능했다. (빌드 20분 후 큰 프로젝트 한번에 배포)
- 토스는
사일로
라고하는 기업내 작은 스타트업이 모이는 방식을 채택했는데,모놀리식
은 이것과 잘 맞지 않는 아키텍쳐였다. 각사일로
에는기획자
,디자이너
,프론트
,백엔드
개발자 4명으로 구성되어 있고 각 서비스에 대한 완전한 권한을 갖는다. -
사일로의 제품마다 제품 경험이 달랐다.
행운퀴즈
- PC대응(IE까지)대출맞춤신청
- 모바일 웹앱카드값돌려막기
- 상태값이 굉장히 복잡하다.
각 서비스 특성마다 사용되는 라이브러리들이 달라지기 시작했고, 서비스를 별도 관리할 필요가 생겼다. 그래서 두번째 아키텍쳐인 마이크로서비스 아키텍쳐
로 변경했다.
이 아키텍쳐에서는 각 사일로
내의 프론트엔드 개발자가 자발적으로 라이브러리를 선택하고 자율적으로 작업할 수 있게 되었다.
- 패키지가 분리되었기 때문에 서비스 마다 라이브러리 의존성 관리가 달라지게 될 수 있었다.
스토리북
,Mobx
,RxJs
,PC대응
등을 서비스 마다 선택적으로 사용했다. - 빌드시간이 획기적으로 줄어들었다.( 20분 → 2~3분 )
- 하나의 서비스가 다른 서비스에 영향을 미치지 않게 되었다.
이렇게 패키지를 나눠서 위와 같은 장점이 생겼지만 반대로 공통화가 어려워 졌다. 서비스마다 라이브러리 버전 파편화도 문제였다. 서비스마다 사용하는 라이브러리의 버전이 달랐다.
새로운 서비스 구축에 많은 비용이 들었다. 레포지토리가 많아지게 되면 잊혀지는 코드들이 생겼다.
이런 부분을 고려해서 Mono Repo
라는 아키텍쳐 도입을 고려했다. 이 아키텍쳐는 패키지는 쪼개도 하나의 Repo에 패키지들을 관리한다. 여러개의 서비스
, 공통 코드
, 라이브러리
들을 하나의 Repo안에서 관리할 수 있게 되었다.
마이크로서비스 아키텍쳐
에서는 1Repo
1Package
이지만 Mono Repo 아키텍쳐
에서는 1Repo
Multiple Package
인걸로 이해된다.
모놀리식은 1Package
Multiple Services
모놀리식 아키텍쳐
Repo
Package
Service
Service
Service
마이크로 서비스 아키텍쳐
Repo
Pacakage
Repo
Pacakage
Repo
Pacakage
Repo
Pacakage
Mono Repo 아키텍쳐 (토스 채택)
Repo
Package
Service
Package
Service
바벨
, emotion js
등이 이런 구조를 채택하고 있다.
토스의 Mono Repo
구조
Repo
libraries
- 컴포넌트 라이브러리
- 디자인 시스템 라이브러리
- eslint
services
- 각 서비스들..
마이크로 서비스
+ 모노 레포
장점
- 설정이 굉장히 간편해짐. (루트에서 설정 가져와서 각 서비스에 사용하면됨)
코드
와이슈
를 관리/검색하기 쉬웠다.- 새로운 프로젝트 구축에 비용이 거의 들지 않았다. (yarn library mylibray, yarn service myservice)로 간편하게 생성