Next.js - Pages

박춘화·2022년 1월 17일
0

NEXT.js

목록 보기
1/2
post-thumbnail

Next.js에서 페이지는 pages 디렉토리 내의 js, jsx, ts, tsx가 내보내는 리액트 컴포넌트다. 페이지 파일의 경로는 페이지의 라우트가 된다.

예시: pages/about.js 페이지 파일을 생성하면 이 페이지의 경로는 /about이 된다.

사전 렌더링

Next.js는 기본적으로 모든 페이지를 사전 렌더링한다. Next.js는 클라이언트 사이드에서 자바스크립트에 의한 렌더링 대신에 사전에 모든 페이지들에 대한 HTML 파일을 생성한다. 사전 렌더링을 사용하면 검색 엔진 최적화(SEO)에 좋은 성능을 보여준다.

사전 렌더링이 이루어진 HTML 파일에는 사용자와의 상호 작용에 필요한 JS 코드를 가진다. 페이지가 브라우저에 로드되면 JS 코드가 실행되면서 사용 준비가 완료된다. (이 과정을 Hydration이라 한다.)

사전 렌더링의 두 가지 방식

Next.js는 두 가지 방식의 사전 렌더링을 지원한다. Static GenerationServer-side Rendering이다. 두 방식의 차이점은 '페이지를 위한 HTML 파일을 생성하는 시점'에 있다.

  • Static Generation(권장됨): 빌드 시점에서 HTML 파일을 생성하고, 매 요청마다 HTML 파일을 재사용한다.
  • Server-side Rendering: 매 요청마다 HTML 파일을 생성한다. (재사용 X)

성능 측면에서 Static Generation을 권장한다. 정적으로 생성된 HTML 파일은 CDN에 캐싱되어 재사용되기 때문이다. 하지만 경우에 따라서는 Server-side Rendering을 사용해야할 때도 있다. 또한, 페이지에 따라 Client-side Rendering을 적용할 수도 있다.

Static Generation

Static Generation을 사용한 페이지는 next build와 같은 방식으로 HTML 파일을 생성하며, CDN에 캐싱되어 매 요청마다 재사용된다. Next.js가 페이지를 생성할 때 데이터를 포함/미포함할 수 있다.

데이터가 미포함된 페이지

일반적으로 Next.js는 데이터 요청이 없는 페이지를 사전 렌더링한다.

function About() {
  return <div>About</div>;
}

export default About;

데이터가 미포함된 페이지들은 빌드 시점에서 개별적으로 HTML 파일이 생성된다.

데이터가 포함된 페이지

몇몇 페이지들은 사전 렌더링 전에 외부 데이터를 요청해야한다. 두 가지 시나리오에 따라 Next.js에서 제공하는 함수들을 적용할 수 있다.

  1. 페이지의 콘텐츠가 외부 데이터를 사용한다면 getStaticProps
  2. 페이지의 경로가 외부 데이터를 사용한다면 getStaticPaths (일반적으로 getStaticProps와 함께 사용)

시나리오 1 예제

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => {
        <li>{post.title}</li>;
      })}
    </ul>
  );
}

// 이 함수는 빌드 시점에 호출된다.
export async function getStaticProps() {
  // 외부 URL에 API 요청을 보낸다.
  const res = await fetch(URL);
  const posts = await res.json();

  // { props : { posts } }를 반환함으로써 Blog 컴포넌트는 'posts` props를 사용할 수 있다.
  return {
    props: {
      posts,
    },
  };
}

export default Blog;

시나리오 2 예제

Next.js는 동적 라우트를 사용한 페이지 생성 기능를 제공한다. 예를 들어, pages/post/[id].jsid 파라미터에 의해 결정되는데 id 파라미터의 값으로 외부에 데이터 요청을 보내야한다.

// 이 함수는 빌드 시점에 호출된다.
export async function getStaticPaths() {
  // 외부 URL에 API 요청을 보낸다.
  const res = await fetch(URL);
  const posts = await res.json();

  // 사전 렌더링에 사용할 경로를 가져온다.
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }));

  // 이렇게 생성된 경로들은 빌드 시점에 사전 렌더링이 이루어진다.
  // { fallback : false } 옵션을 주어 주어진 경로 이외의 경로에 대해 404 에러를 가진다.
  return { paths, fallback: false };
}

// 받은 경로 데이터를 props로 넘겨준다.
export async function getStaticProps({ params }) {
  const res = await fetch(`${URL}/${params.id}`);
  const post = await res.json();

  return { props: { post } };
}

Server-side Rendering

Server-side Rendering은 매 요청마다 HTML 페이지를 생성한다. 페이지에 Server-side Rendering을 적용하기 위해서 getServerSideProps 함수를 호출해야 한다. 이 함수는 매 요청시마다 서버에서 호출된다.

예제

function Pages() {
  // 렌더링 코드
}

// 이 함수는 매 요청마다 호출된다.
export async function getServerSideProps() {
  // 외부 URL에 API 요청을 보낸다.
  const res = await fetch(URL);
  const data = await res.json();

  // props로 데이터를 넘겨준다.
  return { props: { data } };
}

getServerSideProps는 이전의 getStaticProps와 유사하다. 차이점은 getServerSideProps는 빌드 시점이 아닌 매 요청마다 호출된다는 것이다.

요약

  • Static Generation: HTML 파일이 빌드 시점에 생성되며, CDN에 캐싱되어 매 요청마다 HTML 파일을 재사용한다. 페이지에 Static Generation으로 사전 렌더링을 적용하려면 페이지 컴포넌트, getStaticProp (경우에 따라서는 getStaticPaths도)를 export하면 된다. 필요한 경우에는 Client-side Rendering과 혼용할 수 있다.
  • Server-side Rendering: 매 요청마다 HTML 파일을 생성한다. 페이지에 Server-side Rendering으로 사전 렌더링을 적용하려면 getServerSideProps를 export한다. Server-side Rendering은 Static Generation에 비해 느린 성능을 가지므로 꼭 필요할 때만 사용해야 한다.

출처

profile
함께 성장하는 개발자

0개의 댓글