ISR
介紹
- 中文翻作增量靜態重新產生,也稱為 iSSG,算是一種 SSG 與 SSR 混合體
- 幫助大型靜態內容網站可以避免過往因為要新增一篇文章、修正 typo 就要 rebuild 的耗時費力
原理
- 新增頁面
- 類似 lazy loading 概念,新頁面在第一次被請求時才立即被產生
- 在產生過程中,會提供 fallback page 與 loading UI 提示
Next.js 範例:
// In getStaticPaths(), you need to return the list of
// ids of product pages (/products/[id]) that you'd
// like to pre-render at build time. To do so,
// you can fetch all products from a database.
export async function getStaticPaths() {
const products = await getProductsFromDatabase();
const paths = products.map((product) => ({
params: { id: product.id },
}));
// fallback: true 意指找不到的頁面不會 404
// 會改渲染 fallback UI
return { paths, fallback: true };
}
// params will contain the id for each generated page.
export async function getStaticProps({ params }) {
return {
props: {
product: await getProductFromDatabase(params.id),
},
};
}
export default function Product({ product }) {
const router = useRouter();
if (router.isFallback) {
return <div>Loading...</div>;
}
// Render product
}
- 更新既有頁面
- 在使用者請求時,才按需渲染動態頁面,並在特定時間後,自動讓快取失效且能重新產生新頁面
- 快取使用 stale-while revalidate 策略,使用者在 revalidate 前會收到快取版,revalidate 在背景執行無需 rebuild
Next.js 範例:
// This function runs at build time on the build server
export async function getStaticProps() {
return {
props: {
products: await getProductsFromDatabase(),
revalidate: 60, // 強制頁面在 60s 後重驗證
},
};
}
// The page component receives products prop from getStaticProps at build time
export default function Products({ products }) {
return (
<>
<h1>Products</h1>
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</>
);
}
按需求 ISR
- 能透過邊緣網路重新產生和分發頁面,讓全球使用者自動地從邊緣快取看到最新版頁面
- 避免非必要重新產生,且與經典 ISR 相比能降低機器成本
優點
- 動態資料:不需 rebuild 就能支援動態資料
- 效能:幾乎與傳統 SSG 一樣快,重建頁面與資料拉取在背景執行,仍會有一些處理時間
- 可用性:就算新頁面在背景重建失敗,仍可看到前一版頁面
- 穩定性:因為許多頁面仍為靜態建置,對 server 負擔小能維持較好的穩定性
- 適用 CDN,同 SSG 優點