이런 회고록이나 개발일지는 문어체가 아닌 격식체로 작성하려고 합니다.
안지키고 있으면 댓글로 혼내주세요..
2차 팀 프로젝트
프로그래머스 데브코스 FE에 참여하고 벌써 2차 팀 프로젝트를 만들었습니다. 주제는 1차 팀플은 git과 github를 이용한 협업과 기본적인 자바스크립트를 이용한 노션앱을 만드는 것이었는데 이번엔 프로그래머스측에서 제공해주는 api를 이용하여 실제 현업같은 느낌으로 프로젝트에 임할 수 있었습니다.
🌱 프로젝트 주제
제공된 api는 기본적인 CRUD와 회원가입, 로그인 기능이 포함되어 있었습니다.
API를 보자마자 저희 팀은 커뮤니티 SNS 플랫폼을 떠올리게 되었고, 사용자가 자유롭게 소통할 수 있는 플랫폼을 만들고자 하였습니다.
📚 구현 항목
프로젝트에 들어가기에 앞서 프로그래머스측에서 제시한 필수 구현사항 항목들이 있었고 추가 구현사항들이 있었습니다.
필수 구현 항목
- 사용자는 회원가입과 로그인을 할 수 있어야 합니다.
- 사용자는 채널에 올라온 글을 볼 수 있어야 합니다.
- 사용자는 가입자 목록을 볼 수 있어야 합니다.
- 사용자는 가입자를 이름으로 검색을 할 수 있어야 합니다.
- 사용자는 가입자의 정보를 볼 수 있어야 합니다.
- 사용자는 포스트 혹은 가입자를 검색할 수 있어야 합니다.
- 인증된 사용자는 자신의 정보를 변경할 수 있어야 합니다.
- 인증된 사용자는 채널에 올라온 글을 볼 수 있어야 합니다.
- 인증된 사용자는 채널에 포스트를 남길 수 있어야 합니다.
- 인증된 사용자는 포스트를 좋아요 할 수 있어야 합니다.
- 인증된 사용자는 포스트에 댓글을 남길 수 있어야 합니다.
- 인증된 사용자는 자신의 알림 목록을 확인 할 수 있어야 합니다.
- SPA 형태로 만들어주세요.
- 엉뚱한 페이지에 접속하면 404 페이지를 보여주세요.
추가 구현 항목
- 다크 모드를 적용해보세요
- 인증된 사용자는 프로필 이미지 변경 및 포스트를 작성할 때 이미지를 첨부할 수 있어야 합니다. 파일 업로드를 구현해보세요
- 사용자는 현재 접속 중인 사용자를 볼 수 있어야 합니다.
/users/online-users
- 인증된 사용자는 다른 가입자에게 메시지를 보낼 수 있어야 합니다.
- 인증된 사용자는 자신에게 온 메시지 목록을 확인 할 수 있어야 합니다.
- 인증된 사용자는 특정 사용자와의 메시지 대화 내역을 확인 할 수 있어야 합니다.
우리 팀의 추가 구현 항목
위 프로그래머스에서 제시한 구현 항목들을 보면 전형적인 커뮤니티에 필요한 필수적인 요소들만 있는 것을 알수 있습니다. 저희는 완전한 SNS 웹 서비스를 만들기 위해 아래와 같은 기능들을 추가했습니다.
- 반응형
- 겔러리 형태의 이미지 확대
- 무한 스크롤
- 소셜 로그인
- 관리자 페이지
✨ 기획 및 디자인
정말 다행히도 저희 팀은 디자인이 가능한 팀원이 있었습니다.(게다가 잘하시는👍)
프론트엔드 개발자에겐 디자인 역시 무시할 수 없는 영역이고, 센스가 있어야 한다고 생각합니다.
이 블로그 디자인도 나름 마음에 드는데 여러분은 어떤가요..? ㅎㅎ
🔥 트러블 슈팅 및 고민
1. Token 관리
방법 검토
-
쿠키를 사용
- 장점: 브라우저 탭 간 이동이나 브라우저를 닫았다 열어도 토큰(로그인 상태)이 유지됨
- 단점: XSS(Cross-Site Scripting) 공격에 취약하기 때문에, HttpOnly 옵션을 반드시 설정해야 하나, 현재 백엔드가 이를 지원하지 않는 상황
-
Persist 미들웨어와 세션스토리지 사용
- 장점: 로그인 후 사용자 정보를 불러올 때, 렌더링 전에 사용자 정보를 미리 가져올 수 있어 사용자 경험(UX)을 향상시킴
- 단점: 세션스토리지는 브라우저 탭 간 정보가 공유되지 않으므로, 탭 이동 시 로그인 상태가 유지되지 않는 한계가 있음
-
Persist 미들웨어와 로컬스토리지 사용
- 장점: 간단히 토큰을 저장하고 유지할 수 있으며, 브라우저를 닫아도 데이터가 남아 있어 장기적으로 상태를 유지함
- 단점: 로그아웃하지 않으면 토큰이 로컬스토리지에 계속 남아 있어 보안에 취약함. (특히, XSS 공격에 민감하게 노출됨.)
결론
리액트 쿠키와 세션스토리지를 함께 활용하여 보안성과 사용자 경험을 모두 충족하고자 함 => 리액트 쿠키: 유효시간(expiration time)을 설정하여 토큰 만료를 관리함. 추후 백엔드에서 HttpOnly 처리가 가능해지면, 보안성을 더욱 강화할 수 있을 것으로 기대
=> Zustand Persist
: 렌더링 전에 사용자 정보를 불러오는 기능을 제공하여, 로그인 직후 사용자 정보가 없는 상태의 화면이 잠깐 표시되는 문제를 해결함.
2. 무한 스크롤 구현 (Intersection Observer 사용)
Intersection Observer
를 사용한 이유
장점
- 비동기적 처리
- 스크롤 이벤트는 매우 자주 발생하므로, 이를 처리할 때 성능 문제가 발생할 수 있습니다. 반면, Intersection Observer는 지정된 요소가 화면에 보일 때만 실행되어 불필요한 계산을 줄이고 성능을 최적화합니다.
- 성능 우수
- 특정 요소가 뷰포트에 나타날 때만 이벤트가 발생하므로, 스크롤 이벤트를 계속 처리하는 것보다 효율적입니다.
문제점 및 해결 방법
-
게시글 클릭 후 뒤로 가기 시 스크롤과 게시글 초기화
- 문제: 게시글을 클릭하고 뒤로 가기를 하면, 이전에 저장된 스크롤 위치나 게시글 상태가 초기화됩니다.
- 해결: sessionStorage에 offset과 scrollY 값을 저장하여 페이지가 새로고침되거나 뒤로가기 할 때 이를 복원합니다. scrollY는 ref에 저장하여 불필요한 리렌더링을 방지하고 성능을 최적화합니다. 세션 저장: 스크롤 위치가 변경될 때마다 scrollYRef 값을 갱신하고, offset과 scrollY를 sessionStorage에 저장합니다. 만약 뒤로가기로 페이지에 접근하였다면 (navigationType === "POP" 이라면) sessionStorage에서 값을 불러와 데이터를 fetch 합니다.
-
새로고침 시 불러오는 데이터 수가 증가하는 문제
- 문제: 새로고침 후 offset이 증가한 상태에서 데이터를 불러오는 문제가 발생합니다.
- 해결: 만약 처음 데이터를 불러오는 것이라면 loadMoreItems를 실행하지 않도록 합니다. 새로고침 시, scrollState가 없는 경우 기본적으로 6개의 데이터만 로드하도록 설정합니다. 만약 scrollState가 존재한다면, 이를 기반으로 데이터를 로드합니다.
-
sessionStrage에 scrollState가 없을 경우 데이터를 정상적으로 fetch하지 못하는 문제
- scrollState가 있을 경우에만 scrollState를 가져와서 데이터를 fetch하고,(restoreScrollAndFetchData)scrollState가 없다면 데이터를 6개씩 fetch하도록 수정
결과
세션에 scrollState가 없으면 기본적으로 6개의 데이터만 가져오고 scrollState가 저장되어있다면 저장되어있는 정보를 기반으로 데이터를 불러옵니다. 만약 다른페이지로 이동한다면 세션에서 scrollState를 제거합니다.
3. 토글 이벤트 불필요한 HTTP 요청 처리
문제
좋아요 / 팔로우 등 토글 이벤트의 경우 반복적인 HTTP 요청은 서버에 불필요한 부담
해결
- debounce를 이용해서 서버의 요청을 최소화
- useEffect의 의존성으로 debounce값 사용시 불필요한 요청이 발견되어 분기처리를 따로 설정
- 분기 기준은 렌더링의 영향을 주지 않는 useRef를 사용해서 렌더링 최적화
결과
최적화 이전 | 최적화 이후 |
---|---|
⚡️ 결과물
Light Mode | Dark Mode |
---|---|
메인페이지 | 로그인 | 회원가입 | 유저프로필 |
마이페이지 | 게시판 | 게시글 | 게시글 작성 / 수정 |
OPEN API에 문제 발생 시 사이트 진입에 오류가 있을 수 있습니다.
🤓 느낀점과 아쉬운 점
협업과 역할 분담에서 커뮤니케이션 능력이 많이 요구된다는 것을 느꼈습니다. 다양한 시각과 코드 스타일 그리고 컨벤션 관리까지 정하고 개발에 들어가니 더 수월하고 기술적인 성장에도 많은 도움이 됐습니다. 무엇보다 팀원들이 열정이 넘치는게 좋았습니다. 누구하나 빠지는 것 없이 각자 자기가 맡은 역할에 충실했다고 생각합니다.
하지만 이 프로젝트가 실제 현업이라고 생각하면 아직 많이 부족하다고 느꼈고 너무 주먹구구식으로 개발을 하는 느낌을 받았습니다. 빠른 속도로 개발하여 여유가 있었음에도 어떻게 고도화하고 최적화할지 더 고민했어도 되지 않았을까 생각이 들고 Github PR을 정말 현업처럼 사용해보며 코드리뷰를 남겼어도 좋았겠다는 아쉬움도 생겼습니다. 그리고 무엇보다 기획단계에서 좀 더 독창적인 아이디어를 생각해내지 못한 것이 아쉽네요. 다음에 더 좋은 개발경험으로 돌아오겠습니다.