Next

[Next] 정적생성 / getStaticPath()

sian han 2023. 2. 20. 21:29

Next.js 는 기본적으로 모든 pre-render 한다. (클라이언트 사이드의 자바스크립트가 모든 일을 하는 것이 아니라 html 파일을 사전에 만든다는 의미이다. ) 생성된 html 은 필요한 최소한의 자바스크립트 코드가 있고, 브라우저에 의해 로드될 때 그 코드가 실행되어 완전한 페이지를 표현한다. 

 

▶ Pre-Rendering 을 했을 때와 하지 않았을 때의 차이

프리렌더링을 하지 않으면 아무것도 없다가, js 가 로드된 이후에 페이지가 채워지게 된다.

 

 

 

Next.js 처럼 Pre-Rendering 을 하게 되면 초기에 사전에 만들어진 html 들이 나온다. 여기엔 메타 데이터들이 포함되어있다.

이후 js 가 로드된 이후 <Link/ > 와 같은 컴포넌트들이 작동하기 시작한다. 

이것을 하이드레이션이라고 한다. 

하이드레이션은 정적인 무언가에 생기를 불어넣는 작업을 한다. (초기 html 은 정적인데 js 코드가 실행되면서 살아나는거임)

 

 

Pre-Rendering 에는 두가지가 있다. 정적생성과 서버사이드렌더링이다.

개발자는 페이지별로 정적생성을 할지 서버사이드 렌더링을 할지 정할 수 있다.

개발자 : A 와 D 는 정적생성을 하고 B 와 C 는 서버사이들 렌더링으로 진행해야겠어

 

▶ 그렇다면 언제 어떤 방법을 선택해야할까 ?

▷ 페이지를 빌드 시점에 만들어주고 CDN 을 통해서 재사용하기 때문에 대부분의 경우 정적생성이 훨씬 빠르고 좋다.

 

Next.js 에서는 아래의 경우 정적생성하라고 권고하고 있다.

  • 마케팅페이지
  • 블로그게시물
  • 제품목록
  • 도움말, 문서

유저가 요청을 보내기 전에 페이지를 미리 만들어둬도 되는 경우 정적 생성을 선택한다.

 

▷ 항상 최신상태를 유지해야하는 페이지의 경우 서버사이드 렌더링으로 처리한다.

  • 관리자 페이지
  • 분석차트

 

▶ 다이나믹 라우터는 정적생성이 불가능한걸까 ?

Next.js 다이나믹 라우터란 : 페이지의 경로를 동적으로 생성하는 방법이다. 

 

다이나믹 라우터에는 ID 가 있는데 어떤 ID 가 들어올지 모르기 때문에 모든 경우를 위해서 html 을 하나하나 생성해둘 수는 없다. 

그렇지만 만약 ID 의 갯수가 한정적이고 그 리스트를 미리 알 수 있으면 가능하다. => getStaticPath()를 사용한다 ! 

 

▶ getStaticPath()

동적 경로를 가진 페이지를 정적생성할 때 사용되는 함수이다. 

getStaticPath() 는 서버 측에서 실행되며, 빌드 시간에 호출된다. getStaticPath() 는 빌드 시간에 가능한 모든 경로를 생성해야한다. 반환된 경로는 params 객체를 포함하는 객체배열이어야 한다.

 ㄴ params 객체 - 동적 라우팅 경로의 매개변수 이름과 해당 값의 매핑을 나타내는 객체

 

 

▷ getStaticPath() 를 사용해 동적 경로를 가진 페이지를 정적으로 생성해보자.

// pages/posts/[id].js

import { getAllPostIds, getPostData } from '../../lib/posts'

export default function Post({ postData }) {
  return (
    <div>
      <h1>{postData.title}</h1>
      <br />
      <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
    </div>
  )
}

export async function getStaticPaths() {
  const paths = getAllPostIds()
  return {
    paths,
    fallback: false
  }
}

export async function getStaticProps({ params }) {
  const postData = await getPostData(params.id)
  return {
    props: {
      postData
    }
  }
}

위 코드에서는 getStaticPaths() 함수를 사용해 getAllPostsIds() 함수를 호출하여 가능한 모든 포스트의 ID 목록을 가져온다. 

이 함수는 빌드 시간에 호출되며, 반환된 paths 배열은 빌드된 페이지에 대한 경로 목록을 포함한다.

그리고 getStaticProps 함수가 각 경로에 대해 실행되고 해당 포스트의 데이터를 반환한다. 

 

▶ fallback 속성

getStaticPaths() 가 반환한 동적경로 매개변수들 중에서 어떤 것이 유효한지 결정하는데 사용된다. fallback 값으로 true, false, blocking 을 설정할 수 있다.

 

▷ fallback : true 

  • fallback 중에 임시페이지를 보여줌 
  • 요청 받은 경로에 대한 정적 페이지가 없으면 서버측에서 페이지를 렌더링하는 시점에 동적으로 생성한다. 
  • 최초 요청 시에는 비어있는 페이지를 렌더링하며, 다음 요청부터는 생성된 페이지를 제공한다.
  • fallback true 는 페이지가 많은 경우에 유용하다. 
  • 최초 접속 시 props 가 빈 상태로 그려지고, 이후에 백그라운드에서 정적파일로 html 과 json 을 생성해준다. 그리고 Next.js 는 Pre-Rendering 목록에 추가한다. 그리고 두번째 접속부터는 정적 생성된 페이지들을 사용한다.
  • 최초 접속 유저들은 빈 화면을 잠깐 보게되겠지만 이후 접속하는 유저들은 정적파일로 빠르게 제공받을 수 있다. 
  • useRouter 훅 router 객체의 isFallback 속성을 활용해 사용자에게 로딩중임을 알려주도록 하자.
  •  

ex ) getServerSidesProps 함수를 사용할 때 fallback 옵션을 true 로 설정하면 임시페이지를 보여준다.

getServerSidesProps 함수는 매 요청마다 실행되기 때문에, 임시 페이지를 보여주면서 (fallback=true 이므로) getServerSidesProps 함수가 실행되는 것이다.

 

 

▷ fallback : false

  • 요청받은 경로에 대한 정적페이지가 없으면 404 페이지를 반환한다. (페이지에 대한 대응을 해주지 않는다) 
  • fallback 속성이 false 로 설정된 경우, 모든 경로에 대한 페이지가 빌드시간에 생성되어 미리 렌더링된다.

 

▷ fallback : blocking

  • 요청받은 경로에 대한 정적 페이지가 없으면 서버측에서 페이지를 렌더링할때까지 기다린다.

 

 

'Next' 카테고리의 다른 글

[Next] 폴더 구조 및 동작  (0) 2023.02.20
[Next] SSR / SSG / getStaticProps()  (0) 2023.02.20