增量靜態重新產生 (ISR)
Next.js 讓您可以在建置網站後建立或更新靜態頁面。增量靜態再生 (ISR) 讓您可以在逐頁的基礎上使用靜態產生,而無需重建整個網站。透過 ISR,您可以在擴充到數百萬個頁面的同時,保留靜態的優點。
須知:
edge
執行時期 目前與 ISR 不相容,不過您可以透過手動設定cache-control
標頭來利用stale-while-revalidate
。
若要使用 ISR,請將 revalidate
屬性新增至 getStaticProps
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: 'blocking' } will server-render pages
// on-demand if the path doesn't exist.
return { paths, fallback: 'blocking' }
}
export default Blog
當對在建置時預先呈現的頁面提出請求時,它最初會顯示快取頁面。
- 在初始請求後和 10 秒前對頁面的任何請求也會快取並即時處理。
- 在 10 秒的視窗後,下一個請求仍會顯示快取(過時)的頁面
- Next.js 會在背景中觸發頁面重新產生。
- 頁面產生成功後,Next.js 會使快取失效並顯示已更新的頁面。如果背景重新產生失敗,舊頁面仍會保持不變。
當對尚未產生的路徑提出請求時,Next.js 會在第一次請求時對頁面進行伺服器端渲染。後續請求會從快取提供靜態檔案。Vercel 上的 ISR 會在全球範圍內保留快取並處理回滾。
須知:檢查上游資料提供者是否預設啟用快取。您可能需要停用(例如
useCdn: false
),否則重新驗證將無法提取最新資料來更新 ISR 快取。當 CDN(針對被請求的端點)傳回Cache-Control
標頭時,快取可能會發生在 CDN 上。
依需求重新驗證
如果您將 revalidate
時間設定為 60
,所有訪客都會看到您網站的相同已產生版本,時間為一分鐘。使快取失效的唯一方法是有人在經過一分鐘後造訪該頁面。
從 v12.2.0
開始,Next.js 支援依需求增量靜態重新產生,以手動清除特定頁面的 Next.js 快取。這讓您在下列情況下更新網站時更輕鬆:
- 您的無頭 CMS 中的內容已建立或更新
- 電子商務的元資料已變更(價格、說明、類別、評論等)
在 getStaticProps
內,您不需要指定 revalidate
來使用依需求重新驗證。如果省略 revalidate
,Next.js 會使用預設值 false
(不重新驗證),且僅在呼叫 revalidate()
時依需求重新驗證頁面。
須知:中介軟體不會對依需求 ISR 請求執行。相反地,在您想要重新驗證的精確路徑上呼叫
revalidate()
。例如,如果您有pages/blog/[slug].js
和從/post-1
->/blog/post-1
的重寫,您需要呼叫res.revalidate('/blog/post-1')
。
使用按需重新驗證
首先,建立一個只有 Next.js 應用程式知道的機密權杖。這個機密權杖會用來防止未經授權存取重新驗證 API 路由。你可以使用以下 URL 結構手動或透過網路掛勾存取路由
https://<your-site.com>/api/revalidate?secret=<token>
接著,將機密權杖新增為應用程式的環境變數。最後,建立重新驗證 API 路由
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// this should be the actual path not a rewritten path
// e.g. for "/blog/[slug]" this should be "/blog/post-1"
await res.revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}
查看我們的示範以查看按需重新驗證的實際運作並提供回饋。
在開發期間測試按需 ISR
使用 next dev
本機執行時,每次要求都會呼叫 getStaticProps
。要驗證你的按需 ISR 設定正確無誤,你需要建立一個正式版本並啟動正式伺服器
$ next build
$ next start
接著,你可以確認靜態頁面已成功重新驗證。
錯誤處理和重新驗證
如果處理背景重新產生時 getStaticProps
內部發生錯誤,或你手動擲回錯誤,最後成功產生的頁面將會繼續顯示。在接下來的後續要求中,Next.js 會重試呼叫 getStaticProps
。
export async function getStaticProps() {
// If this request throws an uncaught error, Next.js will
// not invalidate the currently shown page and
// retry getStaticProps on the next request.
const res = await fetch('https://.../posts')
const posts = await res.json()
if (!res.ok) {
// If there is a server error, you might want to
// throw an error instead of returning so that the cache is not updated
// until the next successful request.
throw new Error(`Failed to fetch posts, received status ${res.status}`)
}
// If the request was successful, return the posts
// and revalidate every 10 seconds.
return {
props: {
posts,
},
revalidate: 10,
}
}
自架設 ISR
增量靜態再生 (ISR) 在使用 next start
時,會在 自架設 Next.js 網站 中開箱即用。
深入了解 自架設 Next.js。
版本歷程
版本 | 變更 |
---|---|
v14.1.0 | 自訂 cacheHandler 已穩定。 |
v12.2.0 | 依需求 ISR 已穩定 |
v12.1.0 | 新增依需求 ISR(測試版)。 |
v12.0.0 | 新增機器人感知 ISR 回退。 |
v9.5.0 | 新增基本路徑。 |
這有幫助嗎?