🚀 이전 SSR 방식의 프로젝트를 Next.js 14 버전
과 Streaming SSR 렌더링
방식을 이용하여 개선하였습니다.
- 날씨 상태에 따라 상품을 추천해주는 큐레이션 서비스입니다.
- 현재 시간과 기상 상태(눈, 비, 구름)에 따라
애니메이션
이 나타납니다. - 모든 개발 내용을 Issue, PR을 이용하여 기록하고 관리하였습니다.
Streaming SSR - Weather Curation
이전 SSR 프로젝트 - Weather Curation
- 서버 컴포넌트 사용으로 클라이언트의 번들 사이즈가 줄어들어
초기 로딩 속도를 개선
할 수 있습니다. - 내장 fetch 기능을 통해 데이터를 캐싱하고 서버 컴포넌트의 통신은 서버에서 처리하여
네트워크 시간을 개선
할 수 있습니다. - API Routes의 Serverless Function을 이용하여 공용 API의
token 노출 문제를 해결
할 수 있습니다.
- renderToString으로 인해
동기적으로 렌더링하는 SSR
의 단점으로 TTI가 늦춰지는 현상을 개선할 수 있습니다. - Streaming SSR의
점진적 렌더링
으로 초기 로딩 속도 및 TTI 시간을 단축할 수 있습니다.
- 서버에서 query를 prefetch하고 해당 query에 대한 cache를 dehydrate하여 HTML에 삽입합니다.
- hydrate 과정을 거쳐 캐싱된 데이터를 클라이언트에서 사용합니다.
- 현재 날씨와 날씨 리스트 API는 페이지 진입 시
refetch를 하지 않도록 개선
하였습니다.
- 이전 프로젝트 대비
LCP를 2.7초 개선
하였습니다. - 압축률이 높은 avif, webp 포맷을 사용하여
이미지 용량이 40% 이상 감소
하였습니다. - 뷰포트에 보이는 이미지들은 priority 설정을 하여 가장 먼저 로드할 수 있도록 개선하였습니다.
- next config 설정을 통해 srcset에 저장되는 이미지 개수를 제한하여 이미지 로드 시간을 개선하였습니다.
- placeholder의 blur 설정과 사이즈 지정을 통해
layout shift 현상을 방지
하였습니다.
- scroll event는 스크롤마다 이벤트가 발생 하기 때문에 throttle 같은 최적화 작업이 필요합니다.
- 또한, 특정 지점 관찰을 위해 getBoundingClientRect 계산을 할 때마다 reflow가 발생합니다.
- 따라서 브라우저 엔진 내부에서 최적화가 되어 있으며
reflow를 발생시키지 않는
IntersectionObserver API
를 선택하여 구현하였습니다.
- Suspense와 ErrorBoundary를 하나의 파일에서 관리합니다.
- AsyncBoundary 내부의 컴포넌트는 하나의 API만 호출하도록 설계하여
Waterfall 문제를 해결
합니다. - 컴포넌트 내부에서는
비동기 성공 상태와 비즈니스 로직에만 집중하여 개발
할 수 있습니다. - SuspenseFallback, ErrorFallback을 props로 주입할 수 있도록 설계하여 컴포넌트마다 다른 Skeleton을 보여줄 수 있습니다.
- 컴포넌트 에러로 인해
전체 앱이 멈추는 현상을 방지
할 수 있습니다.
- ReactElement 타입의
right
props를 통해 상품 카드 우측 상단에 LikeButton, Checkbox 등의 컴포넌트를 주입합니다. - 요구사항이 변경된다면 right에
주입할 컴포넌트를 교체하는 구조
로 변화에 쉽게 대응할 수 있습니다
공통 컴포넌트들은 재사용성을 높이기 위해 비즈니스 로직을 포함하지 않으며 components/Shared
폴더에 모아 관리합니다.
Text 컴포넌트
의 경우 as 속성을 통해 p tag, span tag 등HTML 태그를 선택
할 수 있는 확장성을 제공합니다.Button 컴포넌트
와 같이 일관된 스타일 적용이 필요한 경우variant
('title' | 'subtitle' | 'body') 속성을 활용하여 스타일을 지정합니다.
- 상품 리스트 스켈레톤과 같이 조립되는 형태로 재사용되는 스켈레톤 컴포넌트는 합성 컴포넌트로 설계하였습니다.
- label을 공통으로 사용하는 Input, Textarea 컴포넌트를 합성 컴포넌트로 설계하여 코드를 재사용합니다.
📦 src
├── 📂 app
| ├── 📂 api
| | ├── 📂 getCurrentWeather
| | ├── 📂 getShoppingList
| | └── 📂 getWeatherList
| ├── 📂 like
| ├── 📂 search
| ├── layout.tsx
| └── page.tsx
|── 📂 components
| ├── 📂 Curation
| ├── 📂 Shared
| ├── 📂 Shopping
| └── 📂 Weather
|── 📂 constants
├── 📂 hooks
├── 📂 store
└── 📂 utils
Category | Technologies |
---|---|
프레임워크 및 언어 | |
서버 상태 관리 | |
전역 상태 관리 | |
스타일링 | |
코드 관리 | |
배포 플랫폼 |