之前寫了兩個 demo
講解了如何實作 SSR
和 SSG
,今天再寫個 demo
說在 ISR
如何實作,
什么是 ISR
ISR
即 Incremental Static Regeneration
增量靜態再生,是指在 SSG
的前提下,可以在收到請求時判定頁面是否需要重繪,如果需要則重新構建該頁面,這樣既擁有了靜態頁面的優勢又可以避免頁面長時間未更新導致資訊過時,且由于在頁面維度驗證,所以每次可以只構建特定的頁面,
ISR
一般適用于符合 SSG
場景,但是卻對頁面的時限性有一定要求時,
如何實作
簡單的 ISR
實作也很簡單,只需要在收到頁面請求時按照更新策略判斷是否需要需要重新生成頁面,如果需要觸發頁面的構建更新,需要注意一般情況下生成頁面不會影響頁面的回應,而是后臺去做構建,
現在就基于之前寫的 SSG demo
,做一下改造讓其支持 ISR
,
修改構建腳本
由于 ISR
構建會同時在構建腳本和服務器中觸發,所以需要對之前的代碼做一些小小的改動,
首先抽離出一個通用的構建函式(由于服務器會使用到盡量避免同步代碼):
import fs from 'fs/promises';
import { renderToString } from 'react-dom/server';
import React from 'react';
import Post from './ui/Post';
import List from './ui/List';
async function build(type: 'list'): Promise<void>;
async function build(type: 'post', name: string): Promise<void>;
async function build(type: 'list' | 'post', name?: string) {
if (type === 'list') {
const posts = await fs.readdir('posts');
await fs.writeFile(
'dist/index.html',
`<div id="root">${renderToString(
<List
list={posts.map(post => {
delete require.cache['posts/' + post];
return { ...require('./posts/' + post), key: post.replace('.json', '') };
})}
/>
)}</div>`
);
} else {
delete require.cache['posts/' + name];
const postInfo = require('./posts/' + name);
const fileName = `dist/posts/${name}.html`;
await fs.writeFile(fileName, `<div id="root">${renderToString(<Post data=https://www.cnblogs.com/zxbing0066/archive/2023/06/27/{postInfo} />)}