NextJS Incremental Static Regeneration(ISR)

iskkiri2022년 08월 06일
Next.js
Incremental Static Regeneration
ISR
NextJS Incremental Static Regeneration(ISR)

이번 포스팅에서는 NextJS의 Incremental Static Regeneration(ISR)에 대해서 소개하겠습니다.

Static Site Generation(SSG)를 이용하여 페이지를 pre-rendering 하는 경우에는 페이지를 수정하여도 변경사항이 반영되지 않습니다. 이미 페이지가 만들어져 있기 때문이죠. 수정사항을 반영하기 위해서는 이미 만들어져 있는 페이지를 재생성하는 방법 밖에 없습니다.

 

페이지의 내용을 수정 또는 업데이트 했을 때, 페이지를 재생성하는 방법은 2가지가 있습니다.

 

  • 이전 포스팅에서 다뤘던 SSR방식인 getServerSideProps를 이용하여 매 요청마다 HTML을 재생성
  • getStaticProps의 revalidate를 설정하여 페이지를 재생성

 

Server Side Rendering(getServerSideProps)을 이용해서 매 요청마다 HTML을 생성하는 것은 페이지의 내용이 자주 바뀌는 것이 아니라면 사용하지 않는 것이 좋습니다.

 

getStaticProps에서 revalidate 설정하여 ISR 구현하는 방법은 다음과 같이 반환하는 객체에서 revalidate 시간() 입력하면 됩니다.

 

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const { id } = params;

  const post = await axios.get<Post>(`/api/post/${id}`);

  return {
    props: { post },
    revalidate: 60, // Incremental Static Regeneration(ISR)
  };
};

 

공식문서에서는 다음과 같이 설명합니다. (공식문서에서는 revalidate를 10초로 설정해뒀습니다.)

 

When a request is made to a page that was pre-rendered at build time, it will initially show the cached page.

  • Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
  • After the 10-second window, the next request will still show the cached (stale) page
  • Next.js triggers a regeneration of the page in the background.
  • Once the page generates successfully, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.

 

저는 위 설명을 보고도 명확하게 이해가 되지 않아서 직접 테스트를 해보며 확인했습니다.

이해를 돕기 위해 예를 들어서 설명하겠습니다. 이 블로그에 다음과 같은 제목과 내용을 갖는 게시물이 있다고 가정하겠습니다.

 

  • 제목: 예제
  • 내용: 예제 text 중입니다

 

(1)

글을 작성하고 나서 확인해보니 'text'에 오타가 있는 것을 확인했습니다.

 

1) 글을 수정하기 위해, 해당 게시물 페이지에 방문합니다. 이것이 pre-rendered 페이지에 첫 요청을 한 것입니다.

2) 'text' -> 'test' 로 수정하고 저장합니다. 이 때, 수정하는데 걸린 시간은 20초가 걸렸습니다.

3) 수정한 내용을 확인하려고 페이지를 계속 새로고침 해보지만 변경된 내용이 나타나지 않습니다. 이는 revalidate가 60초로 설정되어 있기 때문에 남은 40초 동안은 내용을 변경하기 이전에 캐싱된 페이지가 나타나는 것입니다.

4) 첫 요청 이후 60초가 지나고 나서, 페이지를 다시 방문하면 그 때서야 페이지를 재생성하고, 재생성이 성공하면 이전에 캐싱해뒀던 페이지는 무효화하고 변경된 페이지를 pre-render 리스트에 업데이트 합니다.

 

(2)

여기까지는 이해가 어렵지 않을 것이라고 생각합니다. 그럼 이번에는 수정하는 시간이 60초보다 길고(90초), 수정하는 동안 페이지에 어떤 요청도 없을 경우를 예를 들어보겠습니다.(90초 동안 방문자가 아무도 없는 경우)

 

1) 글을 수정하기 위해, 해당 게시물 페이지에 방문합니다. 이것이 pre-rendered 페이지에 첫 요청을 한 것입니다.

2) 'text' -> 'test' 로 수정하고 저장합니다. 이 때, 수정하는데 걸린 시간은 90초가 걸렸습니다. 그리고 첫 요청 이후로 해당 페이지에 아무 요청이 없었습니다.

(90초 동안 방문자가 아무도 없었습니다.)

3) 수정한 내용을 확인하려고 페이지 새로고침을 1~2회 하다보면 변경된 내용이 나타납니다. 이는 revalidate가 60초로 설정되어 있고, 첫 요청 이후 90초가 지난 이후에 페이지를 방문했기 때문에 바로 페이지를 재생성한 것입니다. 재생성하는데 걸리는 시간이 있기 때문에 바로 나타나지는 않습니다.

 

(3)

이번에는 수정하는 시간이 60초보다 길고(90초), 첫 요청 이후 70초가 되는 시점에 요청이 들어온 경우에 대해서 예를 들어보겠습니다.

(70초가 되는 시점에 누군가가 수정하고 있는 페이지에 방문한 경우)

 

1) 글을 수정하기 위해, 해당 게시물 페이지에 방문합니다. 이것이 pre-rendered 페이지에 첫 요청을 한 것입니다.

2) 'text' -> 'test' 로 수정하고 저장합니다. 이 때, 수정하는데 걸린 시간은 90초가 걸렸습니다. 그런데 이번에는 첫 요청 이후 70초가 되는 시점에 누군가가 페이지를 방문했습니다.

3) 수정한 내용을 확인하려고 페이지를 계속 새로고침 해보지만 변경된 내용이 나타나지 않습니다. 이는 revalidate가 60초로 설정되어 있고, 첫 요청 이후 70초가 되는 시점에 재요청이 들어왔기 때문에 이 때 페이지 재생성이 일어났습니다(변경된 내용이 없더라도 재생성은 발생합니다).

따라서 이 시점부터 다시 60초를 카운팅 합니다. 즉, (60 + 70 = 130)초가 되는 시점에서야 변경된 내용을 확인할 수 있습니다. 즉, 글을 수정하고 (130 - 90 = 40)초가 지나서야 변경된 내용을 확인할 수 있는 것입니다.

 

처음 공식문서를 읽었을 때 regeneration의 트리거 시점이 이해가 되지 않아 직접 테스트를 해보면서 확인한 결과입니다.

 

이 블로그는 이전에는 SSR을 적용했었지만, 현재는 SSG + ISR 방식으로 구성되어 있습니다.

그러나 SEO를 위해서 site-map을 제공하는 특정 페이지는 SSR을 적용하고 있는 것도 있습니다. 이도 기회가 된다면 나중에 포스팅을 작성하도록 하겠습니다.

 

잘못된 내용이나 궁금한 내용이 있으면 댓글을 남겨주세요.

NextJS Incremental Static Regeneration(ISR)