avatar
instagramthreads

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 優點

References