프론트엔드 개발 포트폴리오 | 데스크테리어 커뮤니티 사이트
내일배움캠프 4기 웹 개발 과정 React 트랙 수료생 최종 프로젝트 ‘BE MY DESK’를 소개합니다.
Aug 16, 2023
나 다운 공간에서 나 다움을 만들다, 데스크테리어 커뮤니티 사이트. [Be my desk.]
- 사이트 둘러보기 : (링크)
⚒️아키텍쳐
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F0c4f9438-8217-4cd3-8dca-edcc3751cbcf%252F%2525EC%252595%252584%2525ED%252582%2525A4%2525ED%252585%25258D%2525EC%2525B3%252590_%2525EC%2525A0%252584%2525EC%2525B2%2525B4.jpg%3Ftable%3Dblock%26id%3D898eb120-e80c-4a20-8151-3829023b31e1%26cache%3Dv2&w=3840&q=75)
🛠️ 주요기술
- react
- nextJS
- Firebase
- typescript
- react-query
🔥트러블 슈팅
✅ React-Query 로 서버 데이터 효율적으로 관리하기
Trouble, 무엇을 개선할 것인가
- 반복적이고 불필요한 data fetching 방지로 인한 렌더링 속도 향상
- 파이어베이스 제공 onSnapshot - 모든 사용자의 액션을 실시간으로 반영해 data fetching
- 파이어베이스 제공 getDoc - UI 에 데이터 업데이트 반영하려면 무조건 refetching 필요
- useEffect 사용으로, 데이터 업데이트 여부와 상관없이 마운팅시 반복적으로 data fetching
- 서버 data fetching 시, 로딩 및 에러 상태에 대한 처리 코드의 반복
- 서버 데이터 업데이트 시, UI 반영속도 개선 (한박자 느리게 반응하는 UI)
Solution, 어떤 해결책이 있는가
- 비동기 data 처리 및 상태관리 라이브러리 적용, React Query VS SWR
- 캐시 무효화 및 data fetching 시점 설정
- 캐시 데이터 조작으로 UI 업데이트
- Optimistic Updates 로 UI 반영속도 개선
Decision-making, 어떤 의사결정을 내렸는가
- React Query 사용
- React Query 에 ~~ 기능을 사용할 것이기 때문
데스크테리어 공유 커뮤니티의 특성상 실시간으로 게시글 업데이트가 일어날 확률이 낮다.
채팅기능 처럼 다른 사용자의 피드백이 실시간으로 팔로업 하는 것이 필수적이지 않다.
→ staleTime 과 cacheTime 을 길게 잡아 캐싱 데이터를 오래 유지
유저가 변화를 감지하는 포인트 : 본인의 액션이 일어났을 때 (좋아요, 스크랩, 팔로우 등)
→ 캐시 무효화 시점 : 유저 액션 (좋아요, 스크랩 등)이 일어났을 경우
유저가 현재 보고 있는 페이지에서는 액션에 따른 data fetching 을 최소화하자.
→ 캐시 무효화 대상 : 액션이 발생한 데이터를 포함하고 있는 다른 페이지의 데이터
→ 데이터 캐시 조작& 클라이언트 상태값으로 data fetching 없이 현재 페이지의 UI 업데이트
유저의 액션을 바로 UI에 반영시켜 체감 속도를 개선하자.
→ Optimistic Updates 를 사용해 캐시 조작을 통해
서버 통신과 별개로 UI 상에서 유저 액션을 바로 반영
✅ 이미지 압축으로 렌더링 속도 높이기
Trouble, 무엇을 개선할 것인가
- 이미지 최적화 및 렌더링 속도 향상
- build time 줄이기
Solution, 어떤 해결책이 있는가
- nextJS/Image 적용하여 이미지 최적화
- 이미지 압축 관련 라이브러리 적용
Decision-making, 어떤 의사결정을 내렸는가
- 기존 <img> ➡️ next/Image 변환하기
next/Image
요구사항
기존 <img>로 작업된 부분의 최적화가 필요하다
선택지
next/Image를 사용하여 이미지 크기 최적화 적용
의견 결정
<img> ➡️ next/Image로 수정
결과
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F167500db-f370-4fe8-bd41-972ed1c92a81%252F%2525EC%25259D%2525B4%2525EB%2525AF%2525B8%2525EC%2525A7%252580.png%3Ftable%3Dblock%26id%3De1d89b56-a366-44ea-baea-7d444c1b1414%26cache%3Dv2&w=3840&q=75)
next/Image를 사용하여 이미지 용량을 줄여 페이지 로딩 속도를 줄이는데 도움이 되도록 함
- 이미지 업로드 시 이미지 압축하기(라이브러리 사용)
- 클라이언트에서 이미지를 압축해서 전달해주기
- 서버에서 이미지를 리사이징해서 저장하기
- 관련 라이브러리를 찾아 장단점을 따져 적용하기
- next 자체에 이와 관련된 기능이 있는지 찾아 적용하기
browser-image-compression(라이브러리)
요구사항
포스팅을 업로드할 때 이미지의 용량에 따라 업로드가 오래 걸리는 사항이 발생함
따라서 이미지를 핸들링할 필요성을 느낌
선택지
의견 조율
이미지를 글쓰기 페이지에서 업로드 할 때 이미지를 압축해서 용량을 낮추기로 함
의견 결정
클라이언트에서 이미지를 압축시켜 서버(파이어베이스)에 전달하기로 함.
browser-image-compression 라이브러리를 사용하여 원본이미지에 손상을 최대한 줄이는 방향으로 압축을 진행하였음.
결과
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Fc6d10cb1-1fc4-450f-bf60-10e4889c19d5%252F%2525EC%252595%252595%2525EC%2525B6%25259501.jpg%3Ftable%3Dblock%26id%3D0ce5426b-28e0-4d52-8979-6c099f768e6f%26cache%3Dv2&w=3840&q=75)
이미지 압축을 진행하지 않고 고화질의 사진을 업로드해 글을 포스팅하는 경우에는 위와 같이 3,408ms가 걸림.
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Ff7fab654-faa5-4a54-8c95-f62592a36ee5%252F%2525EC%252595%252595%2525EC%2525B6%252595%2525EC%252595%2525A0%2525ED%252594%252584%2525ED%252584%2525B0.jpg%3Ftable%3Dblock%26id%3Dae521c7b-003d-4bc1-98c8-d43d56248d64%26cache%3Dv2&w=3840&q=75)
이미지를 압축하여 포스팅을 한 경우에는 1,547ms로 총 45% 이상 시간이 줄어든 것을 확인할 수 있음. 특히 렌더링 시간이 50% 이상 줄어든 것을 볼 수 있음. 따라서 사용자 경험을 향상 시키는 데 도움을 줄 수 있음.
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Ff0d7cc8a-12cf-4108-a47b-defa6f8995d3%252F%2525EC%25259D%2525B4%2525EB%2525AF%2525B8%2525EC%2525A7%252580%2525EC%252595%252595%2525EC%2525B6%252595%2525ED%252581%2525AC%2525ED%252582%2525A4111.jpg%3Ftable%3Dblock%26id%3D2f584bad-a721-47c2-b1fb-294c231ee0c2%26cache%3Dv2&w=3840&q=75)
이미지를 많이 사용하는 사이트이기 때문에 각각의 이미지 용량도 서버 과부하에 영향을 미칠 것이라고 생각함. 압축을 하지 않고 서버로 전달한 이미지의 용량은 1.23MB임.
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F6a97f6c2-48c3-407a-9c06-bac5965ef50e%252F%2525EC%25259D%2525B4%2525EB%2525AF%2525B8%2525EC%2525A7%252580%2525EC%252595%252595%2525EC%2525B6%252595%2525ED%252581%2525AC%2525ED%252582%2525A42.jpg%3Ftable%3Dblock%26id%3D9a8d8f7d-cca9-482f-9b1e-5edf20bc2d4f%26cache%3Dv2&w=3840&q=75)
압축을 진행한 후 서버로 넘긴 이미지의 크기는 811.346KB로 줄었음.
sharp(라이브러리)
요구사항
vercel에서 배포 후 홈페이지 렌더링 속도가 느려 빠르게 개선 해야 할 필요성을 느낌
선택지
의견 결정
nextJS에서 제공하는 sharp 라이브러리를 적용하여 이미지 옵티마이즈를 진행하기로 함
결과
sharp 설치 후 바로 적용이 되었고, 실제로 페이지 로딩 시간이 줄어듦(측정은 하지 못함)
💖주요기능
포스트 필터링(트렌트, 직업별(개발자, 디자이너, 학생, 게이머)
- 포스트리스트 페이지에서 전체글, 트렌드(좋아요 많은 순), 직업별 필터링(개발자, 디자이너, 학생, 게이머)별로 필터링
- 메인 페이지에서 직업별로 필터링
![포스트리스트 필터링](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Fb544f79a-036d-46dd-aacb-c8d1e5ec3a74%252F%2525ED%252595%252584%2525ED%252584%2525B0%2525EB%2525A7%252581.jpg%3Ftable%3Dblock%26id%3D340d731f-0f28-4a9e-9f6c-93adf59d786e%26cache%3Dv2&w=3840&q=75)
![메인 필터링](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F2f883a9f-7ae9-48b5-9b90-1cdb87821e54%252F%2525EB%2525A9%252594%2525EC%25259D%2525B8%2525ED%252595%252584%2525ED%252584%2525B0%2525EB%2525A7%252581.jpg%3Ftable%3Dblock%26id%3Dd9ed3be2-56a4-4058-8077-3d9397c0efe6%26cache%3Dv2&w=3840&q=75)
검색 1 (포스트의 제목, 내용 검색)
- 상단 오른쪽 검색창에서 글 제목과 내용을 기준으로 검색 가능
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F694f7d47-81b8-4503-abfc-56fc2f54228a%252F%2525EA%2525B2%252580%2525EC%252583%25258911111.jpg%3Ftable%3Dblock%26id%3D2295014d-ea5f-46a4-bf1e-a81c526385d0%26cache%3Dv2&w=3840&q=75)
검색 2 (네이버 오픈 API 사용하여 제품 검색
- 글쓰기 페이지 내 모달 안에서 네이버 쇼핑 검색 가능
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F824bded0-b382-4659-94c7-4aa1a3a18d20%252Fsearchchchchch.jpg%3Ftable%3Dblock%26id%3D3724b4b6-1e2b-4c84-a7b7-51f80487a7f0%26cache%3Dv2&w=3840&q=75)
공유(카카오톡, 페이스북, 링크)
- 드롭다운 형식의 공유하기 버튼 클릭 시 카카오톡, 페이스북, 해당 페이지 링크 직접 공유 선택 가능
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Fbe99a9bf-4d29-4abb-8cf0-2bafda835aed%252Fshare.jpg%3Ftable%3Dblock%26id%3Dca16cfe7-142b-4633-a368-d4ef57b69d6b%26cache%3Dv2&w=3840&q=75)
좋아요, 스크랩, 팔로우
- 마음에 드는 게시물 좋아요와 스크랩 가능
- 계속 소식을 받아보고 싶은 사람 팔로우 가능
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F8f035dfd-b6e3-4454-a3ba-badcd7582b1a%252Ffollow.jpg%3Ftable%3Dblock%26id%3D48f5df76-2e76-445c-b125-2a88f3aaaf08%26cache%3Dv2&w=3840&q=75)
마이페이지 내 마이포스트, 스크랩, 좋아요, 팔로우 조회
- 마이페이지에서 자신이 작성한 게시물, 스크랩 한 글, 팔로우 조회 및 삭제 가능
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F6c8e8ea6-8e62-4fac-895c-598c3e3e449f%252FGIF_2023-03-08_%2525EC%252598%2525A4%2525EC%2525A0%252584_11-12-48.gif%3Ftable%3Dblock%26id%3D53626fe5-a9e6-4a01-a880-4f4b23dd6ebe%26cache%3Dv2&w=3840&q=75)
유저인증(비밀번호찾기, SNS유저 추가정보 입력)
- SNS 로그인 유저의 추가정보 입력(닉네임 중복검사),
- 비밀번호 찾기 시 유저 회원타입(SNS/패스워드 회원가입) 검증
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F1c4c7bf9-4ca0-4b9c-8ea1-fbd09fe0c077%252F%2525E1%252584%252589%2525E1%252585%2525B3%2525E1%252584%25258F%2525E1%252585%2525B3%2525E1%252584%252585%2525E1%252585%2525B5%2525E1%252586%2525AB%2525E1%252584%252589%2525E1%252585%2525A3%2525E1%252586%2525BA_2023-03-08_%2525E1%252584%25258B%2525E1%252585%2525A9%2525E1%252584%25258C%2525E1%252585%2525A5%2525E1%252586%2525AB_11.39.42.png%3Ftable%3Dblock%26id%3Dd159c594-9910-49e4-b83f-2e2860fe70c0%26cache%3Dv2&w=3840&q=75)
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Fec4715e2-8adc-4c6e-84c5-055486a6484f%252F%2525E1%252584%252589%2525E1%252585%2525B3%2525E1%252584%25258F%2525E1%252585%2525B3%2525E1%252584%252585%2525E1%252585%2525B5%2525E1%252586%2525AB%2525E1%252584%252589%2525E1%252585%2525A3%2525E1%252586%2525BA_2023-03-08_%2525E1%252584%25258B%2525E1%252585%2525A9%2525E1%252584%25258C%2525E1%252585%2525A5%2525E1%252586%2525AB_11.39.19.png%3Ftable%3Dblock%26id%3D745f875a-dbc0-4261-bcd3-cc0a027489d7%26cache%3Dv2&w=3840&q=75)
![notion image](https://inblog.ai/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252Ffe6b3510-8afb-46b0-ad59-98a71d1b18de%252F%2525E1%252584%252589%2525E1%252585%2525B3%2525E1%252584%25258F%2525E1%252585%2525B3%2525E1%252584%252585%2525E1%252585%2525B5%2525E1%252586%2525AB%2525E1%252584%252589%2525E1%252585%2525A3%2525E1%252586%2525BA_2023-03-08_%2525E1%252584%25258B%2525E1%252585%2525A9%2525E1%252584%25258C%2525E1%252585%2525A5%2525E1%252586%2525AB_11.39.30.png%3Ftable%3Dblock%26id%3Dd08866a3-65eb-4d66-849b-9ef5a50510f7%26cache%3Dv2&w=3840&q=75)
Share article
Subscribe to our newsletter