본 프로젝트는 제 사이드 프로젝트인 곰터뷰 의 개발과정을 담고 있습니다.
부스트 캠프기간 동안 정말 열심히 만들었던, 곰터뷰 프로젝트는 이미 그 자체만으로 정말 많은 기능을 담고 있었지만, 서비스를 사용하시는 분들에게 이 모든걸 경험시켜드리지 못한다고 생각했습니다.
실제로 서비스에 들어오시는 대부분의 유저들의 평균 머무르는 시간은 1분 대로 사실 landing에서 일부 버튼만 클릭해보고 나가는 것으로 예상되었습니다.
우리 정말 열심히 만들었는데..! 야무지게 유저에게 전달할 방법이 없을까?
사실 제품에 대한 가치를 유저에게 전달하는 방법은 여러가지가 있을 수 있습니다.
대표적으로는 마케팅을 하는거죠. 인스타를 비롯한 이곳저곳에 글을 올리며 공격적으로 마케팅을 수행한다면, 분명 정량적인 수치는 늘 수 있을것이라 생각했습니다.
그렇지만, 프로젝트 내부에서 별도의 마케팅 없이도, 서비스 내부에서 가치를 전달할 수 있는 방법에 대해서 고민해보고 싶었습니다.
부스트캠프를 겪고 프로젝트를 경험하고 개발해보며, 분명 이걸 서비스 내부에서 해결 할 수 있으리라 생각했습니다.
그래서 생각한 방법은 튜토리얼을 제공하는것 입니다.
프로그래머스 에서 영감을 얻었습니다.
프로그래머스는 문제풀이 페이지에서 다양한 기능을 제공하며, 유저에게 그 가치를 튜토리얼을 제공함으로써, 쉽게 그 가치를 전달하고 있었습니다.
누군가가 해냈다면, 못해낼 이유가 없었습니다!
바로 작업을 시작해보기로 했습니다.
어떤 일을 시작할때는 그 업무를 수행하는 목적을 명확히 정해둔다면, 첫 발디딤을 정하는 것이 꽤나 수월해집니다.
이번 업무의 목적은 빠른 시간내에 유저에게 튜토리얼을 제공하는 것입니다.
(빠르게 제공하는 이유는 이미 제출된 포트폴리오에서 해당 서비스에 튜토리얼 기능을 추가해두기 위해서 입니다!!)
그에 따라 모든 컴포넌트를 직접 개발하기보다는, 레퍼런스를 찾아 적절하게 라이브러리를 사용하며, 문제를 해결하려 했습니다.
그래서 찾게된 라이브러리는 총 세가지 입니다.
intro.js vs react-joyride vs react-user-tour
압도적으로 react-joyride의 점유율이 높지만, 적어도 왜 인기가 좋은지 그리고 이 선택에 후회를 하지 않도록 좀 더 학습을 진행해보고 싶었습니다.
각각의 라이브러리에 대해서 간단하게 설명해보도록 하겠습니다.
이 또한 React 전용 라이브러리이며, 사용하기 쉽고 간단한 구성을 제공합니다.
여러가지 선택지가 있었지만, 그래도 결국 react-joyride를 선택하게 되었습니다.
컴포넌트 기반의 설계: React는 컴포넌트 기반의 구조를 가지고 있으며, react-joyride도 이러한 구조를 따릅니다. 이는 사용자가 자신의 애플리케이션에 특화된 투어를 만들 때, React의 컴포넌트를 이용하여 쉽게 통합할 수 있다는 것을 의미합니다.
예를 들어, 특정 컴포넌트에 투어 스텝을 연결하는 것이 간단합니다:
<Joyride
steps={[
{
target: '.my-first-step',
content: '이것은 첫 번째 스텝입니다!',
},
{
target: '.my-second-step',
content: '이제 두 번째 스텝으로 이동합니다.',
},
]}
/>
스타일링의 유연성: react-joyride는 CSS-in-JS, 외부 스타일시트, 인라인 스타일링 등 다양한 방식으로 스타일을 적용할 수 있습니다. 이는 투어의 모양을 애플리케이션의 브랜드와 완벽하게 일치시키거나, 특정 스텝에서만 다른 스타일을 적용하는 것이 가능하다는 것을 의미합니다.
예시로, 특정 스텝의 스타일을 변경하는 것은 매우 간단합니다:
<Joyride
steps={[
{
target: '.my-custom-step',
content: '특별한 스타일의 스텝',
styles: {
options: {
zIndex: 10000,
},
},
},
]}
/>
컨트롤의 유연성: react-joyride는 시작, 정지, 건너뛰기 등 투어의 흐름을 제어하는 다양한 옵션을 제공합니다. 이를 통해 사용자는 투어를 자신의 애플리케이션 논리에 맞게 제어할 수 있습니다.
예를 들어, 특정 조건 하에 투어를 시작하거나 종료하는 것이 가능합니다
(해당 조건이 가장 매력적이었습니다.)
<Joyride
run={this.state.isTourActive}
steps={steps}
callback={this.handleJoyrideCallback}
/>
사용자 경험에 대한 세밀한 조정: react-joyride는 툴팁, 오버레이, 스크롤 등 다양한 UI/UX 요소에 대한 세밀한 조정을 가능하게 합니다. 이는 사용자에게 최적화된 가이드 경험을 제공하는 데 도움이 됩니다.
예를 들어, 스크롤 동작이나 오버레이의 투명도를 조정하는 것이 가능합니다. 물론 그 외에도 수많은 커스텀 속성이 가능했습니다.
<Joyride
steps={steps}
scrollOffset={30}
overlayColor="rgba(0, 0, 0, 0.5)"
/>
지금까지 react-joyride에 대해 가볍에 알아보았습니다. 이제는 개발하면서 유의할점을 짚어봅시다.
튜토리얼 기능을 추가할때 가장 주의했던 부분은 바로
기존의 서비스 로직과의 결합도를 최대한 낮추기
현 시점에서의 서비스을 안내하는 로직과 튜토리얼과의 결합도가 어느정도 떨어져 있을 수 있으나, 서비스가 지속되며 이정도의 결합도 점점 강해질겁니다.
즉, 앞으로 서비스의 로직을 개발하며, 기존의 튜토리얼 로직과의 결합을 항상 조심해야한다는 것이 프로젝트를 개발하며 생산성에 큰 장애가 될것이라 생각했습니다.
그래서 제가 생각한 방법은, 결합도를 낮추면서 책임을 최대한 분산하는것이었습니다.
제가 개발하는 곰터뷰 서비스에서의 튜토리얼은 특히나 페이지 전환이 많이 발생하며, 기존의 react-joyride의 예제를 그대로 사용하는것이 까다로웠습니다.
따라서 저는 세가지 조치를 취했습니다.
사진을 보면, service의 상태를 크게 두가지로 나누어 복잡도를 낮추었으며, 전역으로 상태를 받아 제어할 수 있습니다.
이는 여러 페이지를 오가며, 튜토리얼을 종료하거나 마무리 되었을때, 다른 페이지에서도 동일한 동작을 유도하기 위해서입니다.
의존성을 낮추기 위해서 다음과 같은 컴포넌트를 구현했습니다. 해당 컴포넌트는 내가 step으로 삼고 싶은 컴포넌트를 그저 warraping 하고 해당 내가 원하는 stepIndex만 사용하면 됩니다. 이로 인해서 react-joyride는 현제 컴포넌트의 하위에 있는 dom tree 내부에서 해당 target을 찾아서 연결해주는 기능을 수행합니다.
각 페이지 별로 joyride를 각기 다르게 선언해서, 책임을 분산시켰습니다.
처음에는 서비스 전체를 joyride한개를 사용해서 모든 책임을 담당하려 했습니다.
하지만 여러 페이지를 오가며, 각기 다른 step을 사용하거나 style을 다르게 주어야 할때, 지나치게 하나의 컴포넌트에 책임이 주어진다고 생각했습니다. 이는 현 시점에서 개발하는 저는 바로 대응할 수 있으나 서비스의 규모가 커지고 다른 개발자들이 참여해서 해당 로직을 수정해야할 때 장애가 될 수 있겠다는 생각이 들었습니다.
따라서 각기 다른 페이지별로 각각 다른 ServiceTour 로직을 구성하여 최대한 로직의 책임을 분산시킬 수 있었습니다.
짧은 시간동안에 최대한의 생산성을 내기 위해선 어떤 고민을 해야할지 고민하게 되는 프로젝트 였습니다.
자잘한 디테일들이 있습니다만(현재 페이지에서만 사용되는 상태를 joyride컴포넌트에 넘겨주어 이벤트를 처리하기 등), 더 큰 규모에서 문제를 해결해가는 과정을 담고 싶었습니다.
FE개발자로서 프로젝트를 수행하다보면, 모든 로직을 직접 만들어야겠다는 생각이 종종 들곤합니다. 이정돈 혼자해야지! 라는 생각이 들기도 하고 말이죠.
그렇지만, 어떤 순간에는 혹은 자주 이미 있던 라이브러리를 빠르게 익히고 사용하는것 또한 FE 개발자로서의 역량일것이라는 생각이 들었습니다.
아무튼 여러 라이브러리를 대조하며, 최선의 해결책을 찾아낼 수 있었던 과정이었습니다.
좋은 라이브러리 소개 감사드립니다! 예전에 사이트에 저런 반응형 튜토리얼 있을 때는 귀찮기만 했는데, 생각해보면 그 점 덕분에 사이트에 더 친숙해졌던 것 같아요. 직접 구현하는 걸 엄두도 못했었는데, 신기하네요!