Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- nosql
- db
- this
- Boostrap
- CSS
- github
- url
- til
- firestoredatabase
- API
- SQL
- Protocol
- REACT
- HTML
- Database
- web
- Fetch
- W
- data
- jQuery
- IntersectionObserver
- http
- TMDB
- bootstrap
- supabase
- Github Pages
- JavaScript
- useEffect
- Cloud
- 배포
Archives
- Today
- Total
072DATA
Next.js 4가지 렌더링 본문
4가지 렌더링
CSR(Client Side Rendering)
- 특징
- 브라우저에서 JavaScript를 이용해 동적으로 페이지를 렌더링
- 렌더링의 주체가 클라이언트임
- 장점
- 최초 로드를 완료한 뒤 상호작용이 빠르고 부드러움
- 서버에게 추가적인 요청을 보낼 필요가 없기 때문에, 사용자 경험이 좋음.
- 서버 부하가 적음
- 단점
- 첫 페이지 로딩 시간(Time To View)이 길 수 있음
- JavaScript가 로딩 되고 실행될 때까지 페이지가 비어있어 검색 엔진 최적화(SEO)에 불리함
"use client" // useEffect, useState와 같은 훅을 사용시 꼭 작성해줘야 함
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);
}
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default HomePage;
SSR(Server Side Rendering)
- 특징
- 렌더링 주체가 서버임
- 클라이언트의 요청 시 렌더링
- 장점
- 빠른 로딩 속도(TTV)와 높은 보안성을 제공함
- SEO 최적화 좋음
- 실시간 데이터를 사용
- 마이페이지 처럼 데이터에 의존한 페이지 구성 가능
- 단점
- 콘텐츠가 변경되면 전체 사이트를 다시 빌드해야 하는데, 이 과정이 시간이 오래 걸릴 수 있음. → 서버 과부하
- 요청할 때 마다 페이지를 만들어야 함
2가지 코드 예시
fetch에 no-store 옵션
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products',
{cache: "no-store"});
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default ProductsPage;
page.tsx 컴포넌트에 dynamic 추가
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
export const dynamic = "force-dynamic";
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default ProductsPage;
SSG (Static Site Generation)
- 특징
- 서버에서 미리 페이지를 렌더링하여, 클라이언트에 HTML을 제공하는 방식
- 최초 빌드 시에만 페이지가 생성됨
- 페이지 요청 시 이미 생성된 정적 페이지를 빠르게 제공
- 장점
- 초기 로딩 속도가 빨라 SEO에 유리하며, CDN 캐싱이 가능
- 단점
- 정적 데이터에만 적합하며, 데이터에 의존하는 페이지(예: 마이페이지)에는 부적합
- 서버와의 상호작용이 필요해 CSR보다 인터랙션이 느릴 수 있음
2가지 코드 예시
fetch에 아무 옵션을 주지 않기
// SSG TEST : 아무것도 하지 않으면 SSG!
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default HomePage;
fetch에 force-cache 옵션 주기
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products',
{cache: "force-cache"});
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default HomePage;
ISR (Incremental Static Regeneration)
- 특징
- SSG처럼 정적 페이지를 제공하지만 설정한 주기에 따라 페이지를 재생성함
- 예: 주기가 10분이면 10분마다 변경된 데이터를 반영해 페이지를 업데이트
- 먼저 정적 페이지를 보여주고 이후 서버에서 필요 시 재생성
- 장점
- 정적 페이지를 먼저 제공해 빠른 로딩과 좋은 사용자 경험을 제공하며, 일정 주기로 업데이트해 최신 상태를 유지
- CDN 캐싱 가능
- 단점
- 실시간 데이터를 처리하기엔 한계가 있으며, 데이터 의존도가 높은 페이지에는 부적합
2가지 코드 예시
fetch에 옵션 주기
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
const ProductsPage = async () => {
const response = await fetch('http://localhost:4000/products',
next: {
revalidate: 5,
},
);
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default ProductsPage;
page.tsx 컴포넌트에 revalidate 추가하기
import ProductList from '@/components/ProductList';
import { Product } from '@/types';
export const revalidate = 5;
const HomePage = async () => {
const response = await fetch('http://localhost:4000/products');
const products: Product[] = await response.json();
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
</div>
);
};
export default HomePage;
비교하기
CSR | SSR | SSG | ISR | |
빌드시간 | 짧다 | 짧다 | 길다 | 길다 |
SEO | 나쁨 | 좋음 | 좋음 | 좋음 |
페이지 요청에 따른 응답시간 | 보통 | ㄱ릴다 | 짧다 | 짧다 |
최신 정보인가? | 맞음 | 맞음 | 아님 | 아닐 수 있음 |
'FrontEnd > Next.js' 카테고리의 다른 글
OOTW 프로젝트 - 글 작성 구현하기 ( 이미지 업로드 ) (2) | 2024.10.18 |
---|---|
next.js supabase 이미지 업로드 (0) | 2024.10.15 |
Next.js 메타데이터, 동적 메타데이터, params (1) | 2024.10.08 |
Next.js에서의 라우팅 (페이지 이동) (2) | 2024.09.30 |
Next.js 특징 정리 (0) | 2024.09.27 |