Next.js를 사용한 증분 정적 재생(ISR)에 대한 완전한 가이드

게시 됨: 2022-03-10
빠른 요약 ↬ ISR(증분 정적 재생)은 Jamstack의 새로운 발전으로 사이트를 완전히 다시 만들 필요 없이 정적 콘텐츠를 즉시 업데이트할 수 있습니다. Next.js의 하이브리드 접근 방식을 사용하면 전자 상거래, 마케팅 페이지, 블로그 게시물, 광고 지원 미디어 등에 ISR을 사용할 수 있습니다.

1년 전 Next.js 9.3은 SSG(정적 사이트 생성)에 대한 지원을 출시하여 최초의 하이브리드 프레임워크가 되었습니다. 저는 이 시점에서 약 몇 년 동안 행복한 Next.js 사용자였지만 이번 릴리스로 Next.js가 저의 새로운 기본 솔루션이 되었습니다. Next.js로 광범위하게 작업한 후 저는 Vercel에 합류하여 Tripadvisor 및 Washington Post와 같은 회사가 Next.js를 채택하고 확장할 수 있도록 지원했습니다.

이 기사에서는 Jamstack: ISR(Incremental Static Regeneration) 의 새로운 발전을 살펴보고자 합니다. 아래에서 사용 사례, 데모 및 절충안을 포함한 ISR에 대한 가이드를 찾을 수 있습니다.

정적 사이트 생성 문제

Jamstack 이면의 아이디어는 매력적입니다. 미리 렌더링된 정적 페이지는 CDN으로 푸시할 수 있고 몇 초 안에 전 세계적으로 사용할 수 있습니다. 정적 콘텐츠는 빠르고 다운타임에 탄력적이며 크롤러에 의해 즉시 인덱싱됩니다. 그러나 몇 가지 문제가 있습니다.

대규모 정적 사이트를 구축하는 동안 Jamstack 아키텍처를 채택했다면 사이트 구축을 기다리는 데 몇 시간이 걸릴 수 있습니다. 페이지 수를 두 배로 늘리면 빌드 시간도 두 배가 됩니다. Target.com을 고려해 보겠습니다. 배포할 때마다 수백만 개의 제품을 정적으로 생성할 수 있습니까?

빌드 시간 그래프
정적 사이트 생성의 문제: 빌드 시간은 페이지 수에 따라 선형적으로 확장되기 때문에 사이트가 빌드될 때까지 몇 시간을 기다려야 할 수도 있습니다. (큰 미리보기)

모든 페이지가 비현실적인 1ms 안에 정적으로 생성되더라도 전체 사이트를 다시 작성하는 데는 여전히 몇 시간이 걸립니다. 대규모 웹 애플리케이션의 경우 완전한 정적 사이트 생성을 선택하는 것은 시작이 아닙니다. 대규모 팀에는 보다 유연하고 개인화된 하이브리드 솔루션이 필요합니다.

콘텐츠 관리 시스템(CMS)

많은 팀의 경우 사이트 콘텐츠가 코드에서 분리됩니다. 헤드리스 CMS를 사용하면 콘텐츠 편집자가 개발자 없이 변경 사항을 게시할 수 있습니다. 그러나 기존의 정적 사이트에서는 이 프로세스가 느릴 수 있습니다.

100,000개의 제품이 있는 전자 상거래 상점을 생각해 보십시오. 제품 가격은 자주 변경됩니다. 콘텐츠 편집자가 프로모션의 일환으로 헤드폰 가격을 100달러에서 75달러로 변경할 때 CMS는 웹훅을 사용하여 전체 사이트를 재구축합니다. 새로운 가격이 반영될 때까지 몇 시간을 기다리는 것은 불가능합니다.

불필요한 계산이 포함된 긴 빌드는 추가 비용이 발생할 수도 있습니다. 이상적으로는 애플리케이션이 완전히 재구축할 필요 없이 변경된 제품을 이해하고 해당 페이지를 점진적 으로 업데이트할 수 있을 만큼 지능적입니다.

점프 후 더! 아래에서 계속 읽기 ↓

증분 정적 재생(ISR)

Next.js를 사용하면 사이트를 구축 한 후 정적 페이지를 만들거나 업데이트할 수 있습니다. 증분 정적 재생(ISR)을 통해 개발자와 콘텐츠 편집자 는 전체 사이트를 재구축할 필요 없이 페이지별로 정적 생성을 사용할 수 있습니다. ISR을 사용하면 수백만 페이지로 확장하면서 정적의 이점을 유지할 수 있습니다.

정적 페이지는 ISR을 사용하여 빌드 타임 대신 런타임(온디맨드)에 생성할 수 있습니다. 분석, A/B 테스트 또는 기타 메트릭을 사용하여 빌드 시간에 대해 자신만의 절충안을 만들 수 있는 유연성을 갖추게 됩니다.

100,000개의 제품이 있는 이전의 전자 상거래 상점을 생각해 보십시오. 각 제품 페이지를 정적으로 생성하는 실제 50ms에서 ISR이 없으면 거의 2시간 이 걸립니다. ISR을 사용하면 다음 중에서 선택할 수 있습니다.

  • 더 빠른 빌드
    빌드 시 가장 인기 있는 1,000개 제품을 생성합니다. 다른 제품에 대한 요청은 캐시 누락이 되고 정적으로 주문형: 1분 빌드를 생성합니다.
  • 더 높은 캐시 적중률
    빌드 시간에 10,000개의 제품을 생성하여 사용자 요청에 앞서 더 많은 제품이 캐시되도록 합니다(8분 빌드).
왼쪽에 Jamstack, 오른쪽에 Incremental Static Regeneration을 보여주는 그림
ISR의 장점: 빌드 시 또는 주문형으로 생성할 페이지를 유연하게 선택할 수 있습니다. (A) 더 빠른 빌드 또는 (B) 더 많은 캐시 중에서 선택하십시오. (큰 미리보기)

전자 상거래 제품 페이지에 대한 ISR의 예를 살펴보겠습니다.

시작하기

데이터를 가져 오는 중

이전에 Next.js를 사용한 적이 없다면 기본 사항을 이해하기 위해 Next.js 시작하기를 읽는 것이 좋습니다. ISR은 동일한 Next.js API를 사용하여 정적 페이지를 생성합니다: getStaticProps . revalidate: 60 을 지정하여 이 페이지에 ISR을 사용하도록 Next.js에 알립니다.

증분 정적 재생에 대한 요청 흐름 다이어그램
증분 정적 재생에 대한 요청 흐름의 다이어그램입니다. (큰 미리보기)
  1. Next.js는 페이지당 재검증 시간을 정의할 수 있습니다. 60초로 설정합시다.
  2. 제품 페이지에 대한 초기 요청은 원래 가격과 함께 캐시된 페이지를 표시합니다.
  3. 제품 데이터는 CMS에서 업데이트됩니다.
  4. 초기 요청 후 60초 이전에 페이지에 대한 모든 요청은 캐시되고 즉각적입니다.
  5. 60초 기간이 지난 후에도 다음 요청은 여전히 ​​캐시된(부실) 페이지를 표시합니다. Next.js 는 백그라운드에서 페이지 재생성을 트리거합니다.
  6. 페이지가 성공적으로 생성되면 Next.js는 캐시를 무효화하고 업데이트된 제품 페이지를 표시합니다. 백그라운드 재생성이 실패하면 이전 페이지가 변경되지 않은 상태로 유지됩니다.
 // pages/products/[id].js export async function getStaticProps({ params }) { return { props: { product: await getProductFromDatabase(params.id) }, revalidate: 60 } }

경로 생성

Next.js는 빌드 시 생성할 제품과 주문형을 정의합니다. getStaticPaths 에 상위 1,000개 제품 ID 목록을 제공하여 빌드 시 가장 인기 있는 1,000개 제품만 생성해 보겠습니다.

초기 빌드 후 다른 제품을 요청할 때 Next.js가 "대체"하는 방법을 구성해야 합니다. 선택할 수 있는 두 가지 옵션이 있습니다: blockingtrue .

  • fallback: blocking (선호)
    생성되지 않은 페이지에 대한 요청이 있을 때 Next.js는 첫 번째 요청에서 페이지를 서버 렌더링합니다. 향후 요청은 캐시에서 정적 파일을 제공합니다.
  • fallback: true
    생성되지 않은 페이지에 대한 요청이 발생하면 Next.js는 첫 번째 요청에서 로드 상태의 정적 페이지를 즉시 제공합니다. 데이터 로드가 완료되면 페이지가 새 데이터로 다시 렌더링되고 캐시됩니다. 향후 요청은 캐시에서 정적 파일을 제공합니다.
 // pages/products/[id].js export async function getStaticPaths() { const products = await getTop1000Products() const paths = products.map((product) => ({ params: { id: product.id } })) return { paths, fallback: 'blocking' } }

트레이드오프

Next.js는 무엇보다도 최종 사용자에게 초점을 맞춥니다. "최상의 솔루션"은 상대적이며 산업, 대상 및 응용 프로그램의 특성에 따라 다릅니다. 개발자가 프레임워크의 경계를 벗어나지 않고 솔루션 간에 전환할 수 있도록 함으로써 Next.js를 사용하면 프로젝트에 적합한 도구를 선택할 수 있습니다.

서버 측 렌더링

ISR이 항상 올바른 솔루션은 아닙니다. 예를 들어 Facebook 뉴스 피드는 오래된 콘텐츠를 표시할 수 없습니다. 이 경우 콘텐츠를 무효화하기 위해 SSR 및 잠재적으로 서로게이트 키가 있는 고유한 cache-control 헤더를 사용하려고 합니다. Next.js는 하이브리드 프레임워크이므로 이러한 절충안을 스스로 만들고 프레임워크 내에 머물 수 있습니다.

 // You can cache SSR pages at the edge using Next.js // inside both getServerSideProps and API Routes res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');

SSR 및 에지 캐싱은 ISR과 유사하며(특히 stale-while-revalidate 캐싱 헤더를 사용하는 경우) 주요 차이점은 첫 번째 요청입니다. ISR을 사용하면 사전 렌더링된 경우 첫 번째 요청이 정적으로 보장될 수 있습니다. 데이터베이스가 다운되거나 API와 통신하는 데 문제가 있더라도 사용자는 여전히 적절하게 제공된 정적 페이지를 볼 수 있습니다. 그러나 SSR을 사용하면 들어오는 요청에 따라 페이지를 사용자 지정할 수 있습니다.

참고 : 캐싱 없이 SSR을 사용하면 성능이 저하될 수 있습니다. 사용자가 사이트를 보지 못하도록 차단할 때 매 밀리초가 중요하며 이는 TTFB(Time to First Byte)에 극적인 영향을 미칠 수 있습니다.

정적 사이트 생성

ISR은 작은 웹사이트에 항상 의미가 있는 것은 아닙니다. 재검증 기간이 전체 사이트를 재구축하는 데 걸리는 시간보다 길다면 기존의 정적 사이트 생성을 사용하는 것이 좋습니다.

클라이언트 측 렌더링

Next.js 없이 React를 사용하는 경우 클라이언트 측 렌더링을 사용하는 것입니다. 귀하의 애플리케이션은 로딩 상태를 제공한 후 클라이언트 측에서 JavaScript 내부의 데이터를 요청합니다(예: useEffect ). 이렇게 하면 호스팅 옵션이 늘어나지만(서버가 필요하지 않기 때문에) 절충점이 있습니다.

초기 HTML에서 미리 렌더링된 콘텐츠가 없으면 SEO(검색 엔진 최적화)가 느려지고 덜 동적입니다. JavaScript가 비활성화된 상태에서 CSR을 사용하는 것도 불가능합니다.

ISR 대체 옵션

데이터를 빠르게 가져올 수 있는 경우 fallback: blocking 사용을 고려하십시오. 그러면 로드 상태를 고려할 필요가 없으며 페이지는 캐시 여부에 관계없이 항상 동일한 결과를 표시합니다. 데이터 가져오기가 느린 경우 fallback: true 를 사용하면 사용자에게 로드 상태를 즉시 표시할 수 있습니다.

ISR: 단순한 캐싱이 아닙니다!

캐시의 컨텍스트를 통해 ISR을 설명했지만 배포 간에 생성된 페이지를 유지 하도록 설계되었습니다. 즉, 즉시 롤백할 수 있고 이전에 생성된 페이지를 잃지 않을 수 있습니다.

각 배포는 Next.js가 정적으로 생성된 페이지를 유지하는 데 사용하는 ID로 키를 지정할 수 있습니다. 롤백할 때 이전 배포를 가리키도록 키를 업데이트하여 원자적 배포를 허용할 수 있습니다. 즉, 이전의 변경할 수 없는 배포를 방문할 수 있으며 의도한 대로 작동합니다.

  • 다음은 ISR을 사용하여 코드를 되돌리는 예입니다.
  • 코드를 푸시하고 배포 ID 123을 얻습니다.
  • 귀하의 페이지에 "Smshng Magazine" 오타가 있습니다.
  • CMS에서 페이지를 업데이트합니다. 다시 배포할 필요가 없습니다.
  • 페이지에 "Smashing Magazine"이 표시되면 스토리지에 유지됩니다.
  • 잘못된 코드를 푸시하고 ID 345를 배포합니다.
  • 배포 ID 123으로 롤백합니다.
  • 여전히 "Smashing Magazine"이 표시됩니다.

정적 페이지를 되돌리고 유지하는 것은 Next.js의 범위를 벗어나며 호스팅 제공업체에 따라 다릅니다. ISR은 설계상 캐시가 만료되기 때문에 Cache-Control 헤더를 사용한 서버 렌더링과 다릅니다. 지역 간에 공유되지 않으며 되돌릴 때 제거됩니다.

증분 정적 재생의 예

증분 정적 재생성은 전자 상거래, 마케팅 페이지, 블로그 게시물, 광고 지원 미디어 등에 적합합니다.

  • 전자상거래 데모
    Next.js Commerce는 고성능 전자 상거래 사이트를 위한 올인원 스타터 키트입니다.
  • GitHub 반응 데모
    원래 GitHub 문제에 대응하고 ISR이 정적으로 생성된 랜딩 페이지를 업데이트하는 것을 지켜보십시오.
  • 정적 트윗 데모
    이 프로젝트는 30초 내에 배포되지만 ISR을 사용하여 온디맨드 방식으로 5억 개의 트윗을 정적으로 생성할 수 있습니다.

오늘 Next.js 배우기

개발자와 대규모 팀은 하이브리드 접근 방식과 주문형 페이지를 점진적으로 생성할 수 있는 기능 때문에 Next.js를 선택하고 있습니다. ISR을 사용하면 서버 렌더링의 유연성과 함께 정적의 이점을 얻을 수 있습니다. ISR은 next start 을 사용하여 즉시 작동합니다.

Next.js는 점진적인 채택을 위해 설계되었습니다. Next.js를 사용하면 기존 코드를 계속 사용하고 필요한 만큼 React를 추가할 수 있습니다. 작게 시작하여 점진적으로 더 많은 페이지를 추가함으로써 완전한 재작성을 방지함으로써 기능 작업의 탈선을 방지할 수 있습니다. Next.js에 대해 자세히 알아보고 행복한 코딩을 하세요. 모두들!

추가 읽기

  • Next.js 시작하기
  • Next.js의 스타일링 방법 비교
  • Next.js API 경로를 사용하여 GraphQL 서버를 구축하는 방법