프론트엔드 개발 포트폴리오 | 혼합주 레시피 공유 사이트
내일배움캠프 4기 웹 개발 과정 React 트랙 수료생 최종 프로젝트 ‘OHZU’을 소개합니다.
Aug 16, 2023
오늘의 혼합주 OHZU
본인의 취향에 관심이 많고 혼합주를 선호하는 2030 세대를 위한
자신만의 혼합주 레시피와 비율을 공유하는 커뮤니티 입니다.
✅ OHZU 프론트엔드 목표
직관적인 UX/UI 구성
- 페이지에 들어왔을 때, 5~10초 안에 어떤 컨셉의 서비스인지 유저가 인지할 수 있도록 할 것
- 어떤 버튼을 누르거나, 액션을 취할 때 유저가 예상하는 것들을 보여지도록 할 것
- 모바일 환경에서도 위와 같은 목표를 이루도록 할 것
✨ OHZU 아키텍처 구성
📁 OHZU 사용 스택 및 기술적 의사 결정
1️⃣ Library & Language
React
- 새로고침을 하지 않으며, 사용자 인터렉션에 따라 필요한 부분만 리렌더링이 되도록 하기 위해 사용합니다.
- 컴포넌트 단위의 개발이 가능하여 생산성과 유지보수가 용이하여 사용합니다.
Redux Thunk vs. React-Query (서버 상태 관리)
- React Query
- Redux를 사용하기 위한 보일러플레이트 코드가 많습니다. 반면 React Query를 사용하면 Redux보다 프로젝트 구조가 단순해져 애플리케이션을 유지 보수하기 쉽고, 새로운 기능을 쉽게 구축할 수 있습니다.
- Redux는 API 상태를 관리하기 위한 규격화된 방식이 없습니다. 전역 상태 관리 라이브러리이기 때문입니다. 반면 React Query는 서버 상태를 관리하는 라이브러리입니다. Hook을 사용하여 React Component 내부에서 자연스럽게 비동기 서버 데이터를 사용할 수 있는 방법을 알려줍니다.
JavaScript vs TypeScript
- TypeScript
- JavaScript(이하 JS)는 개발환경에서 에러를 감지하기 어렵습니다(런타임 에러). 반면 TS는 개발중에 조기 버그를 감지할 수 있습니다(컴파일 에러). 따라서 버그 및 예상치 못한 동작 가능성을 줄일 수 있습니다.
- 버그 및 에러를 빨리 캐치할 수 있습니다. 이는 곧 서비스 유지 관리가 수월합니다.
2️⃣ Next.Js
- 검색시 CSR의 단점인 SEO(검색엔진 최적화) 기능을 보완할 수 있습니다.
- SSR 방식을 사용하여 사용자가 초기화면을 볼 때 로딩없이 HTML을 볼 수 있고, JS 다운로드 후 페이지 이동시 CSR 방식으로 브라우저에서 처리하게 하므로 보기 편합니다.
- 직관적인 페이지 기반 라우팅 (/pages/search/cocktail) 기능이 있습니다. 페이지 기반 라우팅 시스템을 채택하는 Next.js는 React보다 페이지 이동을 구현하는 데 있어서 수월합니다. (Client-Side-Navigatin)
- React는 CSR방식이라 검색엔진 최적화에 매우 불리합니다. 반면 Next.js는 검색엔진 최적화에 적합한 SSR 기능과 CSR을 구현하여 React의 단점을 커버합니다.
3️⃣ Axios
- Fetch를 사용하여 데이터를 요청시 Response객체를 담고있는 Promise를 반환합니다.
- fetch로 데이터를 사용하기 위해서는 JSON.stringify()를 사용해야합니다. Promise 객체를 문자열로 변환한 뒤, 데이터를 사용할 수 있습니다.
- 반면, Axios는 즉시 사용할 수 있는 JSON객체를 담고 있는 Promise를 반환합니다.
⇒ 카카오 회원가입/로그인 시, 유저 정보를 JSON으로 즉시 사용하기 위해서 Axios를 선택했습니다.
4️⃣ Tailwindcss
- 서비스 특성상 모바일 유저가 많을 것으로 예상하여, 모바일 반응형 스타일링에 유용한 tailwind를 선택했습니다.
- 클래스 작명에 많은 시간을 소요하지 않고, 유지보수가 편리하여 채택했습니다.
- 일관성 있는 디자인 시스템을 적용할 수 있고, JIT compiler로 인해 제한적이지 않아서 협업에 있어서 편리한 부분들이 많아 채택했습니다.
5️⃣ Firebase
- 직접 Server를 구축하지 않고 손쉽게 데이터를 저장 및 조작할 수 있기 때문에, 백엔드 파트에 소요되는 시간을 줄여 UI/UX 향상에 더 많은 시간을 투자할 수 있으므로 채택하였습니다.
6️⃣ Vercel
- Git이 연동되어 배포 과정이 단순하고 쉬우며 과정을 확인할 수 있어서 채택했습니다.
- CDN서버가 우리나라에도 있어 TTFB가 빠른편이어서 채택했습니다.
🚀 트러블 슈팅
Firebase Method로 검색 기능 구현
문제
저희팀은 부분 검색(Full-text search) 기능을 원했습니다.
하지만 Firebase method로는 정확한 키워드를 입력해야 검색(Exact-text search)이 되었습니다.
ex) “블루레몬에이드” ⇒ “블루레몬에이드” ( O ) / “블루레몬” ⇒ “블루레몬에이드” ( X )
실제로 Firebase Doc에서 자료를 찾아보면, 검색 라이브러리로 Algoria(유료) 등의 라이브러리를 사용하는 것을 권장하고 있습니다.
해결방안
fuse.js 공식 사이트에 들어가서 method를 다 찾아보았습니다.
하나씩 적용해보면서 “threshold, distance” method에서 힌트를 얻었습니다.
- threshould : 단어 검색 시, 엄격함을 조절합니다. (엄격 0.0 ~ 1.0)
- distance : 검색 결과의 유사도를 결정하는 가중치를 입력합니다. (엄격 0 ~ 1000)
⇒ 두 가지 method를 사용하여 검색의 엄격함을 Setting했습니다.
그 결과, fuse.js를 사용하여 저희 팀이 원하는 단어 검색 기능을 구현해냈습니다.
게시물 작성중 페이지 이동 방지
문제
- 게시물 작성중 페이지 이탈시 작성중인 데이터 소실
- 새로고침시 데이터의 소실
- 뒤로가기 실행시 데이터의 소실 및 pathname의 변화
- 글 작성 완료 후 페이지 이동시 페이지 이동이 방지됨
해결방안
- router.events 중 routeChangeStart 함수를 이용하여 route의 경로가 변경되시 시작할때 이동확인 모달과 강제로 error를 발생시켜 페이지 이동을 막는다.
- 새로고침은 event beforeunload 를 사용하여 페이지 이동방지 팝업으로 막는다.
- 뒤로가기 역시 route 변경이기 때문에 1번과 같은 방법으로 막는데, 링크는 router.push 로 인해 변경됨. 현재의 pathname 과 router.asPath 를 비교하여 다를 경우 링크를 변경해준다.
- 글 완료후에 페이지 이동이 생기는데 이때도 페이지 이동방지 모달이 발생하게된다. 글 작성 완료시 완료 확인체크 state를 변경시켜 글 작성완료시 true를 반환하게 하여 페이지 이동을 시킨다.
Dynamic Router 로 보내준 query 를 사용할 수 없는 문제
- 문제
- dynamic router로 query를 보낸 후에 받아서 해당 쿼리로 데이터를 불러오는데, 새로고침시에는 보내준 쿼리가 없기 때문에 데이터를 불러오지 못하는 현상
- 해결방안
- sessionStorage를 이용하여 처음에 받은 쿼리를 저장하여 사용
긴 로딩타임
🛫 서비스 성능개선
- Next.js <Image>를 사용하여 이미지 최적화를 하여 Perfomance를 최대 30% 개선하였습니다.
- <button>과 <Link> 태그에 고유한 aria-lable값을 부여하여 Accessibility를 최대 27% 개선하였습니다.
메인페이지
개선 전
개선 후
글쓰기페이지
개선 전
개선 후
상세페이지
개선 전
개선 후
마이페이지
개선 전
개선 후
유저페이지
개선 전
개선 후
Share article
Subscribe to our newsletter