Closed7
Next.js 12.2で、On-Demand ISRのstableがリリース
参照
※ このスクラップでは、画像やソースコードは下記公式ドキュメントから引用
概要
Next.js 12.2で、On-Demand ISRのstableがリリース
- On-Demand ISRについて
- 再度デプロイしなくても、サイトのコンテンツを更新可能
- ヘッドレス CMSなどによるデータ更新時に、下記のAPIをコールしコンテンツを更新する
- Vercelだと300msec程度でグローバル伝播するとのこと
※ ソースコードは公式ドキュメントから引用
// pages/api/revalidate.js
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 {
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');
}
}
On-Demand ISRがいまいちパッとしない方向けに
そもそもOn-Demand ISRの前に遡って順に大枠を理解する。
下記はNext.js前提の説明。
- Pre-renderingについて
- Pre-renderingの種類について
- ISRについて
Pre-renderingについて
- Next.jsは全てのページ(HTML)を、Backend側で事前に作成する
- 生成された各HTMLは、そのページに必要な最小限のJavaScriptコードと関連づけられ、ページ読み込み時にインタラクティブになる
- 事前に取得したいデータがある場合は、APIを事前にコールするように実装する必要あり(getServerSideProps)
No Pre-renderingについて
- 読み込み時は空のページ
- ページ読み込み後に、クライアントで全て描画する
Pre-renderingの種類について
Static Generation
- ビルド時にHTMLを生成する
Server-side Rendering
- リクエストごとにHTMLを生成する
参照
ISR(Incremental Static Regeneration)について
- ビルド時に一定数のHTMLを生成する
- ビルド時間長くなるので、人気コンテンツに絞り生成するとよい(getStaticPaths)
- HTMLが生成されていれば、そのHTMLを表示する
- クライアントにはキャッシュされたHTMLを返しつつ、キャッシュの時間が過ぎていれば、その後HTMLを再生成する
- HTMLが生成されていなければ、HTMLを生成し、そのHTMLを表示する
※ ドキュメントから引用
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
On-demand Revalidationについて
- 更新用APIを作成して、更新用APIが呼ばれなければキャッシュを更新しない様に変更
- 上記の時間指定と組み合わせることも可能
https://<your-site.com>/api/revalidate?secret=<token>
補足
上記のISRで実現したいキャッシュ関連の機能は、SSRでも実現可能。
※ ただしISRはキャッシュだけではない。以前のデプロイ時のページにロールバックするなども可能
SSRでリクエストごとに生成したHTMLを、CDNのキャッシュに乗せる。
CDNの機能として、時間でキャッシュ破棄しても良いし、特定のタイミングでInstant Purge(即時削除)をしても良い。
ここで説明しているISRのキャッシュ機構に関しては、Next.jsとVercelを組み合わせることで、ものすごく簡単に実現できることが素晴らしい点。
このスクラップは2023/01/23にクローズされました