오늘은 Next.js에서 사용되는 렌더링 방식에 대해서 블로그에 담아보겠습니다. 먼저 렌더링 방식을 설명하기에 앞서 알아야할 주요 개념이 있습니다. 바로 Pre-Rendering과 Hydration입니다. 이 두가지에 대해 먼저 알아보고 갑시다.
Pre-Rendering
Next.js는 렌더링을 할 때, 기본적으로 pre-rendring(사전 렌더링)을 수행합니다. 사전 렌더링이란 서버에서 DOM 요소들을 Build하여 HTML 문서를 렌더링 하는 것을 말합니다.
Hydration
미리 렌더링 된 HTML에 Javascript를 결합하여 이벤트가 동작할 수 있도록 만드는 과정을 말합니다.
이러한 개념을 봤을 때, pre-renderin을 하는 방법은 SSG와 SSR로 나뉘며 둘의 차이는 HTML을 생성하는 시기에 있다고 말할 수 있습니다. 기본적으로는 SSG가 SSR보다 높은 성능을 가지고 있기 때문에 SSG를 사용하는 것을 Next.js에서는 권장하고 있습니다.
- SSG: 빌드 시에 HTML을 만들고 각각의 요청 시 재사용합니다,
- SSR: 각각의 요청 시에 HTML을 만듭니다.
1. SSG (Static Site Generation)
- 빌드 시점에서 페이지를 미리 생성합니다.
- 정적 콘텐츠에 적합하며 매우 빠른 로딩 속도를 제공합니다.
- 콘텐츠 업데이트 시 재빌드가 필요합니다.
SSG 사용 방법
- fetch에 아무 옵션 주지 않기
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
- fetch에 force-cache 옵션 주기
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products',
{cache: "force-cache"});
const products: Product[] = await response.json()
- 결과: 아무리 새로고침 해도 동일한 페이지만 출력됩니다.
2. SSR (Server Side Rendering)
- 빌드 시점에서 페이지를 생성하지 않고 매 요청마다 페이지를 생성합니다.
- 서버에서 페이지를 렌더링하여 클라이언트로 전송합니다.
- SEO에 유리하고 초기 로딩 속도가 빠릅니다.
- 서버 부하가 높을 수 있습니다.
SSR 사용 방법
- fetch에 no-store 옵션 주기
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products',
{cache: "no-store"});
const products: Product[] = await response.json();
- page.tsx 컴포넌트에 dynamic 추가하기
export const dynamic = "force-dynamic";
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
- 결과: 요청이 있을 때마다 지속해서 갱신해줍니다. hydration이 완료되기 전까지의 시간 즉, TTI(Time To Interactive)가 관건입니다.
3. CSR (Client Side Rendering)
- 브라우저에서 JavaScript를 사용하여 페이지를 렌더링합니다.
- 초기 로딩 후 빠른 페이지 전환을 제공합니다.
- SEO에 불리할 수 있으며 초기 로딩 시간이 길어질 수 있습니다.
- 동적 콘텐츠에 적합합니다.
CSR 사용 방법
- "use client" 옵션 주기
"use client"
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
const HomePage = async () => {
const [products, setProducts] = useState([]);
useEffect(()=>{
fetchData();
},[])
const fetchData = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
setProducts(products);
}
- 결과: 요청이 있을 때마다 지속해서 갱신해 줍니다. client side rendering이기 때문에, loading에 관련한 state 제어를 통해 사용자에게 알려줄 수 있습니다.
4. ISR (Incremental Static Regeneration)
- SSG + SSR 장점을 결합한 방식입니다.
- 정적 페이지를 설정한 주기를 바탕으로 재생성합니다.
- 콘텐츠의 신선도를 유지하면서 정적 콘텐츠의 이점을 누릴 수 있습니다.
ISR 사용 방법
- fetch에 옵션주기
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products',
next: {
revalidate: 5,
},
);
const products: Product[] = await response.json();
- page.tsx 컴포넌트에 revaildate 추가하기
export const revalidate = 5;
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
- 결과: 주어진 주기마다 한 번씩 갱신해 줍니다.
'강의' 카테고리의 다른 글
App Router: useRouter (1) | 2024.10.07 |
---|---|
Route Handler와 Server Action (0) | 2024.09.26 |
TypeScript의 개념 (5) | 2024.09.24 |
비동기 및 json-server (0) | 2024.09.10 |
리액트 심화 주차 필수 개념 정리(2) (1) | 2024.09.06 |