[강의] Next.js로 웹사이트 만들기2

김하은·2024년 1월 9일
0

코드잇 강의 정리

목록 보기
60/60

프리렌더링

CSR 시간 순으로 정리

프리렌더링이란?

웹브라우저가 페이지를 로딩하기 이전에 이루어지는 렌더링

  • 크게 정적 생성(Static Generation)과 서버사이드 렌더링(Server-side Rendering)으로 나뉨
  • Next.js에서는 기본적으로 모든 페이지를 정적 생성함

정적 생성(Static Generation)

  • 빌드를 하는 시점에 렌더링을 하는 것
  • 즉, 빌드할 때 html을 만드는 것
  • 빌드: 배포하기 전에 소스 코드를 실행할 수 있는 형태로 만들어 놓는 것
  • Hydration: 이미 렌더링 된 html과 리액트의 데이터를 연결하는 작업

getStaticProps() 함수

  • 정적 생성할 때 필요한 데이터를 받아와서 렌더링하고 싶다면getStaticProps() 함수를 구현하고 export하면 됨
  • 객체의 props 프로퍼티로 넘겨줄 Props 객체를 지정하고, 이것을 페이지 컴포넌트에서 사용할 수 있음
export async function getStaticProps() {
  const res = await axios('/products/');
  const products = res.data;

  return {
    props: {
      products,
    },
  };
}

export default function Home({ products }) {
  return (
    <ProductList products={products} />
  );
}

getStaticPaths() 함수

  • /pages/products/[id].js 와 같이 다이나믹 라우팅을 하는 페이지를 정적 생성을 할 때에는 어떤 페이지를 정적 생성할지 지정해줘야 함
  • getStaticPaths() 라는 함수를 구현하고 export해서 정해줄 수 있음
  • getStaticPaths() 함수에서는 리턴 값으로 객체를 리턴하는데, paths 라는 배열에서 각 페이지에 해당하는 정보를 넘겨줄 수 있음
  • fallback 이라는 속성을 사용해서 정적 생성되지 않은 페이지를 처리해 줄 것인지 지정할 수 있었는데 fallback: true 라고하면 생성되지 않은 페이지로 접속했을 때 getStaticProps() 함수를 실행해 페이지를 만들어서 보여줌
export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '1' }},
      { params: { id: '2' }},
    ],
    fallback: true,
  };
}
  • getStaticProps() 함수에서는 context 파라미터를 사용해서 필요한 Params(context.params) 값이나 쿼리스트링(context.query) 값을 참조할 수 있음
  • fallback: true라고 지정했다면, 필요한 데이터가 존재하지 않을 수 있기 때문에 적절한 예외처리를 해야 하는데 { notFound: true } 를 리턴하면 데이터를 찾을 수 없을 때 404 페이지로 이동시킬 수 있음
export async function getStaticProps(context) {
  const productId = context.params['id'];

  let product;

  try {
    const res = await axios(`/products/${productId}`);
    product = res.data;
  } catch {
    return {
      notFound: true,
    };
  }

  return {
    props: {
      product,
    },
  };
}
  • 만약 fallback: true 를 설정했다면 getStaticProps() 를 실행하는 동안 보여 줄 로딩 페이지를 구현해야 하는데, 페이지 컴포넌트에서 필요한 데이터가 존재하지 않을 때를 처리해 주면 됨
export default function Product({ product }) {
  if (!product) {
    return <>로딩 중 ...</>
  }
  return <>상품 이름: {product.name}</>;
}

서버사이드 렌더링(Server-side rendering)

  • 웹 브라우저가 GET 리퀘스트를 보낼 때 마다 서버가 매번 렌더링 해서 html을 보내줌
  • Next.js 서버에 리퀘스트가 도착할 때마다 페이지를 렌더링해서 보내주는 방식
  • getServerSideProps() 함수를 구현하고 export하면 됨
  • 이때 리턴 값으로는 객체를 리턴하는데 정적 생성때와 마찬가지로 props 프로퍼티로 Props 객체를 넘겨주면 페이지 컴포넌트에서 받아서 사용할 수 있음
export async function getServerSideProps() {
  const res = await axios('/products/');
  const products = res.data;

  return {
    props: {
      products,
    },
  };
}

export default function Home({ products }) {
  return (
    <ProductList products={products} />
  );
}

프리렌더링의 좋은 점

  • 초기 로딩이 빨라짐
    • 처음부터 html이 렌더링 된 상태로 제공되기 때문에 자바스크립트를 로딩해서 리액트가 완전히 실행될 때까지 기다리지 않아도 예쁜 화면이 보임
  • 검색엔진 최적화가 됨
    • 텅 빈 html이 아니라 렌더링 된 html을 받아서 사이트를 파악할 수 있음

정적 생성

  • Next.js에서는 기본적으로 정적 생성을 해줌
  • 정적생성을 하면서 데이터를 가져와서 쓰고 싶다면 getStaticProps라는 함수를 이용하면 됨
  • 정적 생성은 모양이 고정된 페이지를 말하는 게 아니라 빌드할 때 프리렌더링 하는 즉, 빌드할 때 html을 미리 만들어 놓는 것을 말함

정적 생성 vs SSR

홈페이지

  • 홈페이지(/pages/index.js)에서는 상품 데이터가 자주 업데이트되지 않는다고 가정했기 때문에, 정적 생성을 했음
  • 만약에 관리자가 상품을 자주 업데이트하거나, 항상 최신의 상품을 보여 줘야 한다면 서버사이드 렌더링을 선택하면 됨

검색 페이지

  • 검색 페이지(/pages/search.js)에서는 주소에 있는 쿼리스트링 값에 따라서 다른 검색 결과를 보여 줘야 하기 때문에, 서버사이드 렌더링을 했음
  • getServerSideProps() 함수를 구현해서 쿼리스트링에 따라 다른 데이터를 가지고 서버사이드 렌더링을 하도록 구현함

상품 상세 페이지

  • 상품 상세 페이지(/pages/items/[id].js)에서는 항상 최신의 리뷰 데이터를 보여주기 위해서, 서버사이드 렌더링을 했음
  • getServerSideProps() 함수를 구현해서 아이디 값에 따라 다른 데이터를 가지고 서버사이드 렌더링을 하도록 구현했음
  • 리퀘스트가 들어올 때마다 매번 리뷰 데이터를 불러와서 렌더링하기 때문에, 항상 최신의 리뷰 데이터로 프리렌더링할 수 있었음

설정 페이지

  • 설정 페이지(/pages/settings.js)에서는 딱히 데이터를 사용하지 않았기 때문에, Next.js에서 기본적으로 정적 생성을 하고 있음

Next.js에서는 특별한 경우가 아니라면 되도록이면 정적 생성으로 구현할 것을 권장하고 있음
리퀘스트가 들어올 때마다 매번 렌더링을 하는 것보다 미리 렌더링을 해서 저장해 둔 것을 보내 주는 게 훨씬 빠르기 때문임

서버사이드 렌더링을 고려하면 좋은 경우

  • 항상 최신 데이터를 보여 줘야 하는 경우
  • 데이터가 자주 바뀌는 경우
  • 리퀘스트의 데이터를 사용해야 하는 경우 (예: 헤더, 쿼리스트링, 쿠키 등)
    그 외에 특별한 이유가 없다면 되도록 정적 생성을 하는 걸 권장함
profile
아이디어와 구현을 좋아합니다!

0개의 댓글