generated from muhandojeon/study-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# CHAPTER 13 렌더링 패턴 | ||
|
||
## 렌더링 패턴의 중요성 | ||
|
||
크롬 팀은 페이지 전체를 하이드레이션 하는 방식보다 정적 렌더링 또는 SSR 사용을 권장 | ||
|
||
## 클라이언트 사이드 렌더링(CSR) | ||
|
||
거의 모든 UI가 클라이언트에서 생성되고, 처음 요청 시에 전체 웹 애플리케이션 모두 로드 | ||
페이지의 복잡성이 증가하면 페이지 렌더링에 필요한 자바스크립트 코드의 복잡성과 크기도 증가 | ||
크롤러가 색인하기 전에 의미 있는 콘텐츠가 시간에 맞춰 렌더링되지 않을 수 있어 SEO에 불리 | ||
|
||
## 서버 사이드 렌더링(SSR) | ||
|
||
모든 요청마다 HTML 생성 | ||
데이터 fetching을 위한 추가적인 왕복 시간을 줄일 수 있음 | ||
HTML을 서버에서 렌더링하고 클라이언트에서 다시 하이드레이션하는 데 필요한 자바스크립트를 함께 제공하는 것이 핵심 | ||
하이드레이션에는 비용이 따르기 때문에 SSR은 하이드레이션 과정을 최적화하려고 함 | ||
|
||
### 적합한 경우 | ||
|
||
- 사용자 쿠키 정보나 요청 데이터를 기반으로 하는 등 **개인 맞춤형 데이터를 포함하는 페이지** | ||
- 인증 상태에 따라 렌더링 여부를 결정해야 하는 페이지 | ||
- 개인화된 대시보드 | ||
|
||
## 정적 렌더링 | ||
|
||
전체 페이지의 HTML을 빌드 시점에 미리 생성해 다음 빌드 때까지 변경되지 않는 것 | ||
정적인 HTML 콘텐츠는 CDN이나 엣지 네트워크에 쉽게 캐싱됨 | ||
|
||
### 적합한 경우 | ||
|
||
- **자주 변경되지 않고, 누가 요청하든 동일한 데이터를 표시하는 페이지** | ||
- 회사 소개, 문의하기, 블로그 페이지 | ||
- 전자상거래 애플리케이션의 상품 페이지 | ||
|
||
### Next.js도 정적 생성을 지원하는 프레임워크 중 하나 | ||
|
||
#### 리스트 페이지 정적 생성 | ||
|
||
- Pages Router : `getStaticProps()` | ||
- App Router : `fetch`의 `cache` 옵션 | ||
|
||
#### 동적 경로를 사용한 상세 페이지 정적 생성 | ||
|
||
- Pages Router : `getStaticPaths()` | ||
- App Router : `generateStaticParams()` | ||
|
||
#### 클라이언트 사이드 데이터 fetching을 통한 정적 렌더링 (항상 최신 목록을 표시해야 하는 동적인 리스트 페이지) | ||
|
||
웹사이트의 UI를 Skeleton 컴포넌트와 함께 정적으로 렌더링 | ||
동적 목록 데이터를 배치할 위치를 미리 지정 | ||
페이지가 로드된 후 SWR`/`Tanstack Query를 사용해 데이터를 가져옴 | ||
|
||
### 점진적 정적 생성(ISR) | ||
|
||
**SSR + 정적 렌더링 = ISR** | ||
|
||
특정 정적 페이지만 미리 렌더링하고, 동적 페이지는 사용자 요청 시에 on-demand 방식으로 렌더링 → 빌드 시간 단축 | ||
**특정 간격마다 캐시를 자동으로 무효화하고 페이지 다시 생성** | ||
`Stale-While-Revalidate` 전략을 사용해 백그라운드에서 재검증하는 동안 사용자는 캐시된 버전을 봄 | ||
|
||
### On-demand ISR | ||
|
||
|일반 ISR|On-demand ISR| | ||
|:-:|:-:| | ||
|정해진 시간 간격마다 페이지 재생성|특정 이벤트 발생 시에 페이지 재생성| | ||
|요청을 처리한 엣지 네트워크 노드에만 업데이트된 페이지 캐시|엣지 네트워크 전체에 페이지 재생성, 재분배(모든 사용자가 최신 버전 확인)| | ||
|
||
### 정적 렌더링 요약 | ||
|
||
- 순수 정적 렌더링 : **동적인 데이터가 없는** 페이지에 적합 | ||
- 클라이언트 사이드 데이터 fetching을 통한 정적 렌더링 : **로드 시마다 데이터가 새로고침**되어야 하고, **placeholder**를 가진 페이지에 적합 | ||
- 점진적 정적 생성(ISR): **특정 간격** 또는 필요에 따라 재생성되어야 하는 페이지에 적합 | ||
- On-demand ISR : **특정 이벤트 발생** 시 재생성되어야 하는 페이지에 적합 | ||
|
||
## 스트리밍 SSR | ||
|
||
SSR이나 정적 렌더링을 사용하는 것보다 **TTI, FCP 단축 가능** | ||
현재 페이지에 필요한 마크업을 모두 담은 HTML 하나를 생성하는 대신, **chunk로 나눠서 전송** | ||
리액트에 내장된 `renderToNodeStream` 함수를 사용하면 애플리케이션을 작은 조각으로 나눠서 전송 가능 | ||
클라이언트는 **데이터를 받는 동시에 UI를 그리기 시작**할 수 있어 **매우 빠른 초기 로딩 경험 제공** | ||
이렇게 수신된 DOM 노드에 `hydrate` 메서드를 호출하면, 이벤트 핸들러가 연결되어 상호작용 가능 | ||
|
||
## 엣지 SSR | ||
|
||
CDN의 모든 지역에서 서버 렌더링 가능, 거의 0에 가까운 콜드 부트 시간(함수가 처음 실행될 때 발생하는 지연 시간) | ||
|
||
### 활용 사례 | ||
|
||
ex. 지역 특화 리스트 페이지 | ||
리스트만 외부 요청, 페이지 대부분은 정적 데이터로 구성 | ||
리스트 컴포넌트만 서버 사이드 렌더링, 나머지는 엣지 사이드에서 렌더링 | ||
|
||
## 하이브리드 렌더링 | ||
|
||
어떤 상황에서든 최적의 결과를 제공하기 위해 여러 가지 렌더링 방식 결합 | ||
Next.js는 리액트 서버 컴포넌트와 App Router를 결합해 하이브리드 렌더링 지원 | ||
|
||
## 점진적 하이드레이션 | ||
|
||
**각 노드를 시간에 따라 개별적으로 하이드레이션하여 필요한 최소한의 JS만 요청하는 방식** | ||
페이지에서 덜 중요한 부분의 하이드레이션을 지연시켜 JS 양을 줄이고, 사용자에게 필요한 노드만 하이드레이션 | ||
서버에서 렌더링된 DOM 트리가 파괴되고 즉시 다시 생성되는 SSR의 문제 방지할 수 있음 | ||
애플리케이션을 여러 조각으로 나누어 뛰어난 성능을 제공하는 것을 목표로 함 | ||
|
||
### 완전한 점진적 하이드레이션을 위한 요구사항 | ||
|
||
- 모든 컴포넌트에 SSR 사용 가능 | ||
- 개별 컴포넌트 또는 조각 단위로 코드 스플리팅 지원 | ||
- 개발자가 정의한 순서대로 클라이언트 사이드에서 각 조각 별 하이드레이션 지원 | ||
- 이미 하이드레이션된 조각에서 사용자 입력 가능 상태 유지 | ||
- 지연된 하이드레이션이 적용되는 조각에 로딩 중임을 표시 가능 | ||
|
||
리액트의 동시성 모드(concurrent mode) 기능 덕분에 요구사항 충족 | ||
동시성 모드 = 여러 작업을 동시에 처리하면서도, 우선순위에 따라 작업 전환 가능 | ||
|
||
## 아일랜드 아키텍처 | ||
|
||
정적인 HTML 위에 독립적으로 전달될 수 있는 상호작용 아일랜드를 통해 JS 전송량을 줄이는 패러다임 | ||
컴포넌트 기반 아키텍처 | ||
정적/동적 아일랜드로 구분된 페이지 뷰 제안 | ||
정적 콘텐츠로 이루어진 페이지의 SSR 지원 | ||
|
||
|점진적 하이드레이션|아일랜드 아키텍처| | ||
|:-:|:-:| | ||
|하향식 하이드레이션 구조|각 컴포넌트가 자체적으로 하이드레이션 스크립트 가짐| | ||
|페이지가 개별 컴포넌트의 스케줄링 및 하이드레이션 제어|하이드레이션 스크립트는 페이지의 다른 스크립트와 독립적으로 비동기 실행| | ||
|
||
### 장점 | ||
|
||
- 성능 : JS 코드의 양이 감소해 페이지 로드 속도 빨라짐 | ||
- SEO : 모든 정적 콘텐츠가 서버에서 렌더링되므로 SEO에 유리 | ||
- 중요 콘텐츠 우선순위 | ||
- 접근성 | ||
- 컴포넌트 기반 | ||
|
||
### 단점 | ||
|
||
- 아직 초기 단계라서 사용 가능한 프레임워크가 적고, 직접 아키텍처 개발해야 함 | ||
- 소셜 미디어 애플리케이션처럼 상호작용을 위주로 한 페이지에는 적합하지 않음 (수천 개의 아일랜드가 필요할 수 있음) | ||
|
||
## 리액트 서버 컴포넌트 | ||
|
||
서버에서 실행되도록 설계된 컴포넌트로, 상태를 가지지 않음 | ||
RSC는 번들 크기를 0으로 줄임 → 결과적으로 클라이언트 사이드 JS 번들 크기 감소 | ||
서버 컴포넌트와 클라이언트 컴포넌트 사이의 매끄러운 코드 전환 경험(knitting) 가능 |