본문 바로가기

Next.js

Next.js 5-1. ISR(Incremental Static Regeneration)

  ISR(Incremental Static Regeneration)은 Next.js에서 제공하는 정적인 페이지를 빌드할 때 매번 다른 전체 페이지를 다시 빌드하는 것이 아니라 변경된 부분만 빌드하고 나머지는 캐시 된 결과를 사용하는 정적 페이지를 업데이트하는 기능이다.

  ISR을 사용하면 페이지를 빌드할 때, 변경될 가능성이 있는 부분만 미리 빌드하여 캐시에 저장한다. 그리고 사용자가 해당 페이지를 요청할 때 미리 빌드한 부분은 캐시에서 가져오고 변경될 가능성이 있는 부분은 실제 데이터를 사용하여 업데이트한 후에 페이지를 반환한다. 이를 통해 정적 페이지의 빌드 시간을 줄이고, 업데이트된 데이터를 빠르게 반영할 수 있다.

  예를 들어 블로그 포스트 목록 페이지에서 새로운 포스트가 추가되는 경우, 해당 포스트에 대한 정보만 다시 빌드하고, 나머지는 캐시 된 결과를 사용하여 페이지를 업데이트할 수 있다. 이를 통해 포스트 목록 페이지를 빨리 업데이트할 수 있다. 

  Next.js에서는 getStaticProps와 함께 revlidate 옵션을 사용하여 ISR을 구현할 수 있다. revalidate 옵션은 페이지가 캐시 된 시간을 설정하여, 이 시간이 지난 후에 사용자가 페이지를 요청하면, 서버에서 해당 페이지를 다시 빌드하여 업데이트된 페이지를 제공한다.

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

// 이 함수는 서버 측에서 빌드 시 호출된다.
// 다음과 같은 경우 서버리스 함수에서 다시 호출될 수 있고,
// 유효성 재검사가 활성화되고 새 요청이 들어온다.
export async function getStaticProps() {
  const res = await fetch('http://.../posts')
  const posts = await res.json()
  
  return {
    props: {
      posts,
    },
    // Next.js는 요청이 들어올 때나 최대 10초마다 한 번 페이지 재생성을 시도할 것이다.
    revalidate: 10,
  }
}

// 이 함수도 서버 측에서 빌드 시 호출된다.
// 만약 경로가 생성되지 않으면 서버리스 함수에서 다시 호출될 수 있다.
export async function getStaticPaths() {
  const res = await fetch('http://.../posts')
  const posts = await res.json()
  
  // 게시물을 기반으로 사전 렌더링하려는 경로를 가져온다.
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  
  // 빌드 시 오직 이 경로만 사전 렌더링한다.
  // {fallback: 'blocking'}은 경로가 없다면 on-demand로 서버에서 페이지를 렌더링한다.
  return { paths, fallback: 'blocking' }
}

export default Blog

 

 

  • On-Demand Revalidation

  On-Demand Revalidation은 Next.js에서 제공하는 ISR의 확장 기능으로, 미리 정의된 시간이 아닌 사용자가 페이지를 요청할 때마다 캐시 된 페이지를 업데이트하는 기능이다.

  예를 들어, 블로그 포스트 상세 페이지에서 사용자가 댓글을 작성하거나 좋아요를 누르는 경우, 해당 페이지는 동적인 데이터를 가지고 있으므로 정적으로 미리 빌드할 수 없다. 그러나 해당 페이지를 매번 요청할 때마다 새로운 데이터를 가져오도록 하면, 사용자들은 빠르게 업데이트된 정보를 볼 수 있다.

  On-Demand Revalidation은 revalidate 옵션을 사용하여 구현할 수 있다. revalidate 옵션에 숫자 값을 지정하면 해당 페이지가 캐시 된 후 일정 시간(초단위)이 지나면 새로운 페이지로 업데이트된다. 이때 사용자가 페이지를 요청하면 서버에서 해당 페이지를 다시 빌드하고 업데이트된 페이지를 제공한다.

  On-Demand Revalidation은 정적 페이지와 동적 페이지 사이의 중간 형태로 동적인 데이터를 가지고 있으면서도 빠른 페이지 업데이트를 가능하게 한다. 이는 사용자 경험을 개선하고 서버 부하를 줄일 수 있는 좋은 방법이다.

 

 

  • On-Demand Revalidation 사용방법

  먼저 Next.js 앱에서만 알 수 있는 비밀 토큰을 만든다. 이 함호는 재검증 API 경로에 대한 무단 액세스를 방지하는 데 사용된다. 다음 URL 구조를 사용하여 경로에 액세스 할 수 있다. 그리고 secret키를 앱의 환경 변수로 추가한다.

// pages/api/revalidate.js

export default async function handle(req, res) {
  // 유효한 요청인 확인하기 위해 secret 키를 확인한다.
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }
  
  try {
    // 재작성 경로가 아닌 실제 경로여야 한다.
    // 예를 들어 '/blog/[slug]'인 경우 '/blog/post-1'이어야 한다.
    await res.revalidate('/path-to-revalidate')
    return res.json({ revalidated: true })
  } catch (err) {
    // 만약 오류가 있으면 Next.js는 마지막 성공적으로 페이지를 표시하는 것을 계속한다.
    return res.status(500).send('Error revalidating')
  }
}

'Next.js' 카테고리의 다른 글

Next.js 6. Client-side data fetching  (0) 2023.04.26
Next.js 5-2. ISR(Incremental Static Regeneration)  (0) 2023.04.25
Next.js 4-3 getStaticPaths  (0) 2023.04.24
Next.js 4-2. getStaticPaths  (0) 2023.04.24
Next.js 4-1. getSaticPaths  (0) 2023.04.24