프론트엔드 데브코스 5,6차 단위 기간 회고, kiwing 회고 (2/2)
1편에 이어서 작성하는 5,6차 단위기간 회고 2/2 편이다. 이번에는 기술적인 부분이랑 마무리를 언급하고 회고를 마쳐보려고 한다.
⚙️왜 CSR 기반으로 한 React를 사용했을까? (기술스택 의사결정)
우리는 왜 기술스택을 정하면서 많은 고민을 했을까? 지금부터 우리 팀이 초반에 고민했던 내용을 잘 떠올려 기술해 보고자 한다.
요즘 프론트엔드의 가장 큰 관심사 중 하나는 SSR(Server Side Rendering)이다. SSR이 각광받는 이유는 바로 SEO 최적화가 굉장히 용이하고 초기 로딩속도가 빠르다는 장점이 있다. 특히 많은 개발자들이 SEO 최적화를 이유로 SSR을 더 많이 사용하고 있을 것이다.
SSR을 지원하는 방식은 다양한데 주변에서 가장 많이 쓰이는 것은 React에 프레임워크 성격을 부여해 주는 Nextjs가 있고 Vue 기반으로 한 Nuxtjs 그리고 다른 다양한 SSR을 기본적으로 지원해 주는 프레임워크를 사용하는 것 같았다.
여기까지만 얘기한다면 `그런 장점이 있는 프레임워크를 바로 도입하면 되잖아 뭐가 문제야?`라고 말할 수 있다. 하지만 우리가 그런 프레임워크를 선정하기에는 제약조건이 있었다.
간단하게 언급해 보면 다음과 같다.
1. 학습 비용이 많이 필요했다.(팀)
React를 기반으로 한 프로젝트 경험이 팀원 모두 있었기에 Nextjs 도입을 고려하지 않은 것은 아니나, 우리 팀 모두 Next는 한 번도 사용해 본 경험이 없다는 문제점이 있었다. Next를 학습할 때 발생하는 라우팅 이슈나 서버 컴포넌트 이슈 등에 대처하기 힘들 것이라는 생각이 들었다.
Next에 대한 내용뿐만 아니라 스타일링 라이브러리 역시 그 비용 중 하나였다. Next를 사용하면 CSS-in-JS 방식의 스타일링이 익숙한 우리에게 추가적인 해결책 혹은 새로운 스타일링 라이브러리에 대한 학습 비용 또는 해결 과정이 필수적으로 수반되어야 했다.
2. Next의 격변(팀)
우리가 프로젝트를 시작할 즈음 Next 버전이 13에서 14로 업데이트되었다. 이는 기존 개발자들에게 많은 혼란을 야기할 정도로 많은 구성이 바뀌었다고 하는데 그런 면에서 학습에 혼돈이 생길 가능성이 높다고 판단했다.
위 두 가지 이유가 팀 관점에서 제약사항이 있었고 추가적으로 개인적인 의문점? 도전사항? 도 두 가지 있었다.
- CSR은 웹 크롤러가 탐지를 못하나? (개인)
이 부분은 사실여부를 떠나서 굉장한 호기심이 있었다. 왜냐하면 검색할 때마다 어떤 사람은 요즘 크롤러봇은 JS를 실행시키기에 가능하다고 하는 반면에 어떤 사람은 절대 안 된다고 단언하기도 했기에 혼란스러웠다. 그래서 직접 눈으로 확인해보고 싶었다.👀
- SSR...? 얼마나 어렵나..? 도전..? (개인)
무모한 걸까? 아니면 바보 같은 걸까? SSR이 얼마나 어려울까에 대한 생각이 들었다. 실제로 구현하면서 어떻게 돌아가는 건지에 대해 원리가 알고 싶었다. 그래서 `React에서 SSR을 구현해 보면 어려울까?` 이런 생각을 했고 도전도 해봤다. 이 개인적인 부분은 회고 말미에 추가적으로 후술 하도록 하겠다.
위에서 언급한 이유들은 우리 팀원들 대부분 공감했고 그래서 우리 팀은 기존에 우리가 가진 기술을 더 잘 다듬기로 했다. React 기반으로 프로젝트를 진행하되 이전보다 더 이해하기 쉽고 명확한 역할을 가진 코드를 잘 구성하고자 했다.
♻️ UI 라이브러리? 공통 컴포넌트?
이어진 우리의 고민은 UI 라이브러리에 관련된 내용이었다. 설계 과정에서 우리 프로젝트는 반복되는 컴포넌트들이 많을 것으로 예측되었고 웹, 모바일을 모두 대응해야 한다는 조건이 있었다.
굉장히 여러 고민이 겹쳤었다. 기능도 겹치는 부분이 많을 것 같고, 그 안에서 디자인의 통일성이나 자율성을 부여해야 한다는 조건이 있었다. 그래서 UI 라이브러리에 대한 선정 이야기가 나왔는데, 아무래도 우리 팀 주제는 사용자 상호작용이 조금 많은 편이고 또 그런 외부 UI 라이브러리를 커스텀하기에는 학습의 비용과 커스텀의 불편함이 있을 거라고 판단했다.
그런 고민들을 하던 우리의 결론은 공통 컴포넌트와 합성 컴포넌트를 작은 단위(버튼, 박스 등)로 만들기로 했다. 그리고 그에 대응해서 이슈, PR 단위를 잘게 나눠서 진행하기로도 결정했다.
그리고 그 안에서 자율성을 가져가면서도 통일성을 부여하기 위해서 단위 부분은 모두 어떠한 값을 받아도 다 커스터마이징이 가능하도록 구현하였고, 기본 값들을 부여하면서 통일성 있는 UI를 구성하려고 노력했다.
그렇게 우리는 여러 공통, 합성 컴포넌트를 구현하여 프로젝트를 잘 마무리할 수 있었다. 다만 지금 와서 드는 약간의 아쉬운 점이라고 하면 `관심사 분리`에 대해서 더 디테일하게 논의가 되었으면 하는 아쉬움이 있지만 논의만 안되었을 뿐 전반적으로 관심사 분리 역시 나쁘지 않게 지켜진 것 같다.
✈️실 서비스를 위한 고민들
이번에 가장 신경 썼던 요소 중 하나는 사이트 노출과 외부 인원 유입이었다. 그러기 위해서 여러 가지 설루션을 나름 도입해 봤다.
첫 번째로 LightHouse 지표이다.
접근성 점수가 조금 아쉬운 부분이 있긴 하지만 핵심 페이지에서 SEO 점수를 모두 만점을 만들기 위해서 노력했다. robots.txt랑 sitemap.xml 파일을 직접 작성해서 등록하고 실제 코드 로직에서 팀원들 모두 시멘틱태그와 웹 표준, 웹 접근성을 준수했다. 또한 메타태그와 같은 부분도 놓치지 않았고 그 결과 핵심 3개의 페이지에서는 모두 SEO 100점을 달성할 수 있었다.
두 번째로 외부 분석 도구이다.
우리는 총 3가지 분석 도구를 적용했다. GA4, hotjar, Sentry이다. GA4를 통해서 유입 지표를, hotjar를 통해서 사용자 데이터 분석을, Sentry를 통해서 사용자 에러 로그를 확인하고자 했다. 그리고 실제로 위에서 수집된 데이터를 기반으로 우리 서비스를 수정, 보완하기도 하였다.
세 번째로는 외부 등록 및 홍보이다.
실제 사용자를 모으고 싶다는 목적으로 외부 사이트 2군데에 등록을 했고, 실제로 많은 조회수를 기록하고 유입도 있는 것을 확인할 수 있었다.
많은 사람들이 은근히 관심을 표해줘서 기뻤다..!
🏃`코딩`을 잘하기 위해 했던 고민
이번 프로젝트에서 우리는 코딩을 잘하고 싶었다. 4명의 프론트엔드 개발자가 개발을 하면서 conflict도 안 나고, 다른 사람의 코드를 유지보수할 때도 잘 진행될 수 있도록 하는 그런 구조를 만들어보고 싶었다.
가장 먼저 도입했던 것은 스쿼시 머지였다. 스쿼시 머지를 도입한 이유는 `여러 작업자와 여러 브랜치, 기능별 작업 속도 차이에 따른 여러 버전의 존재`와 `커밋 히스토리의 간소화` 때문이었다.
우리 팀은 최대한 작은 단위로 PR을 날리기로 컨벤션을 정했다. 따라서 초반에는 특히나 더더욱 작업이 많아지고 잦아질 것이라고 예상했고, 이런 우리의 상황에서 기존의 머지 전략과 리베이스 머지 전략의 경우 충돌이 많이 날 것이라고 판단했다. 실제로 나의 경우에, 이전 프로젝트에서 잦은 충돌로 인해 팀원들이 매우 고생했었다.
그런 근거를 가지고 도입을 진행했고 충돌이 아예 없진 않았으나 확실히 작업을 하는데에 있어서 편했고 작은 단위에 PR으로 인해 히스토리 관리도 만족스러운 성과를 거둘 수 있었다.
그리고 MSW 도입, 활용 경험 역시 이번 프로젝트에서 얻은 성과이다. MSW는 해당 카카오 기술블로그를 보고 참조했고, 궁금하다면 꼭 읽어보길 권장한다. 간략하게 MSW에 대해서 소개하자면 `프론트엔드에서 API 요청을 보내면 서버에서 실제로 응답을 보내는 것처럼 낚아채서 데이터를 반환해 주는 라이브러리`이다.
웹개발 사이클 특성상, 백엔드의 초창기 API가 확립되기 전까지 프론트엔드의 적극적인 개발은 힘들다. 이 문제는 개발 기간을 늘어나게 한다는 큰 문제점을 발생시키는데, 이를 해결하고 싶었고 그래서 MSW를 도입했다.
그리고 MSW 성과는 예상대로 좋았다. 초창기 한 2주 정도 꾸준히 MSW를 통한 컴포넌트, 간단한 페이지 개발을 진행했고 초기 일정을 많이 단축시킬 수 있었다.
그리고 colocation 방식이나, 리뷰 Pn룰 등등 기존에 사용해서 사용 경험이 좋았던 여러 방식들도 같이 채용했다.
개인적으로는 라이브러리에 대한 고민을 조금 했다. 프론트엔드 개발에서 라이브러리는 떼어 놓을 수 없다. 라이브러리가 없이 개발을 진행한다면,,, 어우 상상하기도 싫다. 하지만, 그런 라이브러리도 선택할 때 기준이 있어야 한다고 생각한다. 이전에 4기 선배님과 멘토님과 잠시 이야기를 나눌 때 이런 얘기를 들었다. `라이브러리 유지보수 1년 넘으면 안 써요`
그리고 이후에 그 이유에 대한 이야기들이 쭉 나왔는데 갑자기 사용하던 라이브러리가 사라진다거나... 유지보수가 너무 안 돼서 보안 문제가 생긴다거나... 아예 호환자체가 안 되는 경우도 많다고 하셨다.
그런 생각을 들으며 라이브러리를 잘 선택하는 것도 좋은 코드를 작성하는 방법 중 하나라고 생각이 들었던 찰나에 이번에 bodyScrollLock이라는 라이브러리를 사용할 뻔했다. 모달이 생겼을 때 외부 스크롤을 방지해 주는 이 라이브러리는 이전 프로젝트에서 팀원이 사용했던 라이브러리라 그대로 적용하려고 했는데, 현재 글 쓰는 기준 마지막 업데이트가... 3년 전이었다.
그래서 한 번 직접 구현에 도전해 보았다. 모달이 생길 때 직접 DOM에 접근하여 body태그의 스크롤을 잠그고, 이후 모달이 사라질 때는 다시 해당 잠금을 풀어주는 방향으로 구현했다. 모바일에서 예외처리를 하지 않았던 이슈가 생겨 한참 찾았지만... 그리고 생각보다 코드는 별거 없었지만.. 나름 근거를 가지고 작성한 코드였다.
생각보다 쓸 내용이 많다. 분석툴 3가지(Hotjar, Sentry, GA4)랑, 웹 페이지와 모바일 페이지를 동시에 구현하다 발생했던 여러 이슈들, 그리고 데모 페이지와 SSR까지...
Hotjar는 해당 포스팅을 참조하면 좋을 것 같다. Sentry는 에러 처리를 위해 도입했고, GA4는 Hotjar와 유사한 목적으로 도입했다.
웹 페이지와 모바일을 동시에 서비스하는 우리 페이지 특성상 웹/모바일을 분리구현해야 하는 것이 필수였다. 아무리 미디어태그를 사용한다지만, 모바일 화면은 그냥 웹 화면 하나 구현하는 거랑 다를 게 없었다. 생각보다 시간과 공수가 오래 걸렸고, 듣지도 보지도 못한 신기한 오류가 생기기도 했다. 막 하이라이팅이 된다거나... 그런...
특히 OS에 따라 고려해야 할게 많았다. 아이폰의 경우 일단 뒤로 가기 버튼이 따로 없기에 디자인에서 그런 부분을 잘 고려해야 했고 그리고 safe area이슈가 있었다. 또 안드로이드에서는 기본 뒤로 가기 동작이 브라우저 히스토리 뒤로 가기 동작과 동일해져서 사용자가 종료하려면 수많은 뒤로 가기를 눌러야 하는 문제점들이 있었다. 해당 문제점은 스크립트를 삽입하며 내비게이션 바 기준 홈, 허브, 공유된 꾸러미 페이지에 있을 경우에는 뒤로 가기를 누르면 앱을 종료하는 형태로 스크립트를 짜주어서 해결했다.
위 내용들은 간단한 내용이라 짧게 언급했고 이제 마무리로 SSR 얘기를 잠깐 하고 마무리를 지어보도록 하려고 한다.
🚨실패!
일단 이게 무슨 내용인가 하면, 구현한 SSR 템플릿에서 컴포넌트가 업데이트되면 styled-components의 className이 달라지는데 그게 반영이 안 되는 내용이다. 즉, 위에서 언급한 SSR 구현일기는 이 이슈를 해결하지 못해서 실패했다.
우리 서비스에는 데모 페이지가 있다. 이스터 에그와 같은 기능도 실험하고, Hotjar와 같은 처음 적용하는 기능이나 MSW도 해당 페이지에서 실험을 진행하고 이후 서비스에 반영하였다. SSR 템플릿도 만들어서 적용해보려고 했는데... 실패했다.
일단 구현하려고 했던 방식은 Vike라는 라이브러리를 활용해서 구현하려고 했다. 이게 무엇긴가 하면은 Vite에서 만든 vite-plugin-ssr이라는 라이브러리가 있는데 해당 라이브러리의 계승자..? 후계자..?이다.. 기존 프로젝트를 Nextjs나 Nuxtjs처럼 SSR 형태로 동작할 수 있게 도와주는 라이브러리였고, 특히 styled-components를 사용했던 우리 팀에 적합하게 구현하려면 이 방식이 딱일 것 같았다.
그래서 나름 공식문서를 읽으며 구현을 시도했는데 아쉽게도 실패했다.
약간의 핑계를 대자면 자료가 너무 없었다 일수도 있을 것 같지만, 더 곰곰이 생각해 보니 더 근본적인 문제는 SSR의 방식을 제대로 몰랐던 것 같아서이다. 단순히 `서버가 렌더링 해주겠지`가 아닌 `html은 동적으로 어떻게 만들지?` `API 데이터는 어떻게 붙이고 렌더링 하지?` `스타일은 어떻게 입히지?`의 고민들이 선행되었어야 했던 것 같다.
물론 프로젝트를 하면서 그런 고민들이 쉽지는 않았고, 그래서 못했던 것 같다. 그래서 조금 더 근본적인 단계로 돌아가서 다시 해보려고 이 레포지토리를 만들었다. 만들어두고 잠시 이것저것 일정이 생겨서 이력서와 코테에 집중했었는데, 다시 집중해보려고 한다.
⌛마치며
재미있었던 데브코스 마지막 프로젝트였다. 아이디어도 모두가 채택한 아이디어였고, 팀원들도 너무 좋았다.
다만 위에서 언급한 점을 제외하고 아쉬운 점을 얘기해보면, 모바일 페이지에서의 일정 산출 실패, 2 depth 이상의 고민의 부재, 근본적인 추상화와 함수 역할에 대한 고민이 약간 부족했던 것 같다.
하지만 매 프로젝트는 그렇다. 아쉬운 부분은 어쩔 수 없이 생기고, 다음 프로젝트가 있다면 나아가되 만약 없다면 이전 프로젝트를 다시 톺아보고 개선하는 시간을 가지면 된다.
앞으로 프로젝트 개선점으로 생각나는 것은 테스트 코드 작성, 가상 스크롤, 여러 최적화 로직, 에러 바운더리 추가, 함수 역할 분리, 패턴 적용 등등 을 진행할 예정이다. 그래서 서버가 내려갔지만, AWS 프리티어 혹은 소과금 형태로 프로젝트를 이어나가려고 한다.(팀원들과 모두 합의 하에)
인프라 세팅적인 부분에서도 그렇고, MSW나 모바일 환경 구현 등 새로운 것들을 많이 얻었던 프로젝트였다.
진짜 개발...package.json이 뭔지도 모르는 시절이 있었는데 많이 성장한 것 같다. 물론 성장하면서 느끼는 점은 더더욱 내가 말하는 감자임을 느끼게 하지만...ㅠㅠ
이번 프로젝트도 멈추지 말고 더욱 개선해보면서 성장해 나가야겠다.
'개발 > 회고록' 카테고리의 다른 글
성장의 이정표, 데브코스 프론트엔드 5기 수료 후기 (6) | 2024.05.30 |
---|---|
2024년 2회 정보처리기사 필기 전공자 합격 후기 (0) | 2024.05.24 |
[프론트엔드 데브코스 월간 회고] 5,6차 단위기간(24.01.19 ~ 24.03.25) 프로젝트 kiwing 회고 (1/2) (3) | 2024.04.07 |
프로젝트에서 팀장 역할을 맡으며 했던 고민들 (3) | 2024.01.28 |
[프론트엔드 데브코스 월간 회고] 4차 단위기간(23.12.19 ~ 24.01.18) 프로젝트 looky 회고 (14) | 2024.01.23 |