ISR(Incremental Static Regeneration)은 SSG 방식으로 생성된 정적 페이지를 일정 시간을 주기로 다시 생성하는 기술입니다. 이는 SSG의 빠른 성능과 SSR의 최신 데이터 제공이라는 장점을 결합한 방식입니다.
기존 SSG 방식은 빌드 시점에 모든 페이지가 생성되기 때문에, 데이터가 변경되면 전체 사이트를 다시 빌드해야 한다는 단점이 있습니다. ISR은 이 문제를 해결하여 특정 페이지만 지정된 시간 간격으로 재생성할 수 있게 해줍니다.
Next.js에서 ISR을 구현하는 방법은 매우 간단합니다. getStaticProps 함수의 반환 객체에 revalidate 속성을 추가하면 됩니다.
export const getStaticProps = async () => {
const [allData, someData] = await Promise.all([
fetchDatas(),
fetchSomeData(),
]);
return {
props: {
allData,
someData
},
revalidate: 3, // 3초마다 페이지 재생성
};
};
위 코드에서 revalidate: 3은 페이지가 3초마다 재검증된다는 의미입니다. 이는 다음과 같은 방식으로 작동합니다.
이 방식을 통해 사용자는 항상 빠른 페이지 로딩 속도를 경험하면서, 일정 시간 내에 최신 데이터를 볼 수 있습니다.
하지만 사용자의 행동에 따라 데이터가 업데이트되는 페이지나 실시간 데이터가 중요한 페이지, 사용자별 맞춤형 콘텐츠를 제공하는 페이지에서는 ISR을 적용하기 어렵습니다.
위에 설명한 ISR을 적용하기 어려운 페이지에 ISR을 적용하기 위해 On-Demand ISR이라는 기능이 있습니다. 이는 정해진 시간 간격이 아니라, 특정 이벤트가 발생했을 때 페이지를 재생성할 수 있게 해주는 기능입니다.
On-Demand ISR을 구현하려면, API 라우트를 생성하여 res.revalidate() 함수를 호출하면 됩니다.
// /api/revalidate.ts
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
await res.revalidate("/"); // 홈페이지에 On-Demand ISR 적용
return res.json({ revalidate: true });
} catch (err) {
res.status(500).send("Revalidation Failed" + err);
}
}
이렇게 하면 /api/revalidate 엔드포인트에 요청이 들어올 때마다 홈페이지가 재생성됩니다.
export default async function handler(req, res) {
try {
// 여러 페이지 재검증
await Promise.all([
res.revalidate('/'),
res.revalidate('/products'),
res.revalidate(`/products/${req.body.productId}`),
]);
return res.json({ revalidate: true });
} catch (err) {
return res.status(500).send('Error revalidating');
}
}
Promise.all: 인수로 전달한 배열 안에 들어있는 모든 비동기 함수를 동시에 실행시켜주는 메서드
On-Demand ISR API는 누구나 접근하게 하면 안되기 때문에, 다음과 같은 보안 조치를 추가할 수 있습니다.
export default async function handler(req, res) {
// 비밀 토큰 확인
if (req.query.secret !== process.env.REVALIDATION_TOKEN) {
return res.status(401).json({ message: 'Invalid token' });
}
try {
await res.revalidate('/');
return res.json({ revalidate: true });
} catch (err) {
return res.status(500).send('Error revalidating');
}
}
이렇게 하면 ?secret=your_token 형태로 올바른 토큰을 제공하는 요청만 페이지를 재생성할 수 있습니다.
ISR과 On-Demand ISR은 Next.js가 제공하는 매우 강력한 렌더링 전략으로, 정적 사이트의 성능 이점을 유지하면서도 콘텐츠의 최신성을 보장할 수 있게 해줍니다.
정적 사이트 생성(SSG)과 서버 사이드 렌더링(SSR) 사이의 이상적인 중간점을 제공하여, 개발자가 각 페이지의 특성에 맞는 최적의 렌더링 전략을 선택할 수 있도록 합니다.