무엇
resumeAndPrerender는 prerender(또는 이전 resumeAndPrerender)가 미완성으로 남긴 트리를 이어받아, 다시 정적 HTML로 완성하는 API다. react-dom/static의 Web Streams 버전이다.
이름이 비슷한 resume과 헷갈리기 쉬운데, resume은 스트리밍 SSR로 잇고 resumeAndPrerender는 정적 생성(SSG)으로 잇는다는 점이 다르다.
import { resumeAndPrerender } from 'react-dom/static'
import { getPostponedState } from './storage'
async function handler(request: Request) {
const postponed = await getPostponedState(request)
const { prelude } = await resumeAndPrerender(<App />, postponed)
return new Response(prelude, { headers: { 'content-type': 'text/html' } })
}
무슨 일이 일어나나
prerender가 Suspense 경계에서 멈추면 postponed를 저장해둔다. 나중에(예: 재생성 잡, 백그라운드 재시도) resumeAndPrerender에 그 값을 넘기면, 멈춘 지점부터 다시 렌더링을 이어 최종 정적 HTML을 만든다. 이번에도 다 못 끝나면 새 postponed가 나오고, 다시 resumeAndPrerender를 부르는 식으로 여러 번 이어갈 수 있다.
resume 계열과 마찬가지로 nonce는 지원하지 않는다 — 프리렌더링 결과는 여러 요청에 재사용되는데 nonce는 요청마다 달라야 하기 때문이다.
사용법
import { resumeAndPrerender } from 'react-dom/static'
import { getPostponedState, savePostponedState } from './storage'
async function regenerate(pageId: string) {
const postponed = await getPostponedState(pageId)
const { prelude, postponed: stillPending } = await resumeAndPrerender(<App />, postponed)
if (stillPending) {
await savePostponedState(pageId, stillPending)
}
return prelude
}
signal로 중간에 끊을 수 있고, onError로 서버 에러를 로깅한다. 클라이언트에서는 최종 HTML을 hydrateRoot로 인터랙티브하게 만든다.
실무 예시
정적 생성 결과를 재생성(ISR류)하는 파이프라인에서 쓴다. 최초 prerender가 느린 데이터 소스 때문에 멈췄을 때, 이후 백그라운드 작업에서 resumeAndPrerender로 다시 불러 완성된 정적 페이지를 만들어 캐시에 채운다.
왜 중요한가
아주 니치한 API다. 정적 생성을 여러 단계로 쪼개 이어가는 프레임워크의 재생성 로직 안에서나 마주친다. 이름과 역할이 겹치는 네 API(prerender/resume/resumeAndPrerender/resumeAndPrerenderToNodeStream) 중 "정적 생성을 정적 생성으로 잇는" 쪽이라는 것만 구분하면 된다.
Reference