072DATA

Next.js 4가지 렌더링 본문

FrontEnd/Next.js

Next.js 4가지 렌더링

0720 2024. 10. 2. 11:43

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 나쁨 좋음 좋음 좋음
페이지 요청에 따른 응답시간 보통 ㄱ릴다 짧다 짧다
최신 정보인가? 맞음 맞음 아님 아닐 수 있음