Next.js ISR과 On-Demand-ISR

이정수·2024년 9월 15일
0

NEXT

목록 보기
6/7

ISR ( Incremental Static Regeneration)

증분 정적 재생성 이란, SSG 방식으로 생성된 정적 페이지를 일정시간을 주기로 다시 생성하는 기술이다.

  • 빌드타임에 생성된 페이지에 유통기한을 설정
  • 유통기한이 끝나기 전에는 계속 똑같은 페이지 응답
  • 유통기한이 끝난 이후에는 Next서버에서 다시 새로운 페이지를 정적으로 생성
  • 이후 접속요청에서는 새로운 페이지를 반환

으로 이해하면 쉽다.

그렇다면 만약 유통기한이 60초인 페이지가 ISR로 만들어졌다고 가정할 때, 61초에 페이지를 요청하면 새로운 페이지가 올까? 그것은 아니다.

  • 60초가 지나기 전에는 버전 1의 페이지를 반환한다.
  • 60초 이후에 접속요청이 발생하면 이때는 일단 원래의v1반환후 새로운 페이지를 재생성된다.
  • 이후 요청에서는 v2버전의 페이지가 반환된다.

장점

  • 매우 빠른 속도로 응답 가능 ( 기존 SSG 방식의 장점 )
  • 최신 데이터 반영가능 ( 기존 SSR 방식의 장점 )

페이지에 적용하기

index페이지에서 3초 주기로 isr을 적용해보자

ISR을 적용하는 방식은 간단한데 getStaticProps함수 내부의 리턴문에 revalidate 옵션을 추가하면 된다.

export const getStaticProps = async () => {
  const [allBooks, recoBooks] = await Promise.all([
    fetchBooks(),
    fetchRandombooks(),
  ])

  return {
    props: {
      allBooks,
      recoBooks,
    },
    **revalidate: 3, // ISR 방식으로 동작, 3초주기로 페이지 재생성**
  }
}

ISR 방식 적용이 어려운 페이지

💡 시간과는 관계없이 사용자의 행동에 따라 데이터가 업데이트 되는 페이지

ex) 커뮤니티 사이트의 게시글 페이지

  • 게시글 수정: 페이지 데이터를 업데이트 해야 함
  • 게시글 삭제 : 페이지를 제거해야 함

이처럼 시간이 아닌 사용자의 행동에 따라 데이터에 변화가 생기는 페이지에 ISR방식을 ㅈㅓㄱ용했을 경우 몇가지 문제점이 발생하다.

60초의 유통기한을 가진 ISR방식의 페이지가 있다고 가정하자.
만약 어떤 사용자A가 30초에 이 페이지 내부의 게시글을 수정했고, 사용자B가 50초에 이 페이지를 방문한다면? B는 페이지가 새롭게 만들어질 60초가 되기 전까지는 수정이전버전의 페이지를 봐야 한다.

혹은 이 페이지에 24시간동안 어떤 사용자도 접속을 하지 않다가 하루가 지나고 나서 사용자A가 방문을 했다고 하자. 사용자를 오매불망기다리던 서버는 수정이 이루어 지지 않아도..60초마다 불필요하게 페이지를 재생성했어야 한다.

Q) 그러면 SSR로 처리하면 안돼나요?

SSR의 경우, 브라우저가 요청할때마다 매번 페이지를 사전 렌더링 하기 때문에 응답시간이 느려지게 되고, 동시접속자가 많다면 서버 부하가 커지게 된다.

때문에 등장한것이 on-demand ISR 방법이다.

On-Demand ISR

요청을 받을 때 마다 페이지를 다시 생성하는 ISR 방식이다. 즉 페이지의 업데이트를 트리거링 할 수 있다.

앞선상황의 비유로 살펴보면, 24시간동안 사용자를 기다리던 서버는 이제 게시글 수정이 일어났을 때에만 revalidate요청으로 페이지를 다시 만들면 되는 행복한 서버가 되었다.

이런 방식을 사용하면 대부분의 페이지에 최신 데이터를 공급할 수 있으면서도 정적인 페이지를 유지할 수 있다.

[ pages/api/revalidate.ts ]

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    await res.revalidate('/') 
    return res.json({ revalidation: true })
  } catch (err) {
    res.status(500).send('revalidation failed')
  }
}
  • res.revalidate('/') : revalidate할 페이지의 경로를 전달

브라우저의 url에서 localhost:3000/api/revalidate 으로 요청을 보내면 인덱스 페이지의 재생성이 이루어 진다.

이런 ISR방식은 대부분의 케이스를 커버할 수 있는 강력한 방식으로, 대부분의 next로 구축된 앱서비스에서는 활발히 사용됨

profile
keep on pushing

0개의 댓글