欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解React?ISR如何實(shí)現(xiàn)Demo

 更新時(shí)間:2023年07月07日 09:58:57   作者:嘿嘿不務(wù)正業(yè)  
這篇文章主要為大家介紹了React?ISR如何實(shí)現(xiàn)Demo詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

什么是 ISR

之前寫了兩個(gè) demo 講解了如何實(shí)現(xiàn) SSR 和 SSG,今天再寫個(gè) demo 說(shuō)在 ISR 如何實(shí)現(xiàn)。

ISR 即 Incremental Static Regeneration 增量靜態(tài)再生,是指在 SSG 的前提下,可以在收到請(qǐng)求時(shí)判定頁(yè)面是否需要刷新,如果需要?jiǎng)t重新構(gòu)建該頁(yè)面,這樣既擁有了靜態(tài)頁(yè)面的優(yōu)勢(shì)又可以避免頁(yè)面長(zhǎng)時(shí)間未更新導(dǎo)致信息過(guò)時(shí)。且由于在頁(yè)面維度驗(yàn)證,所以每次可以只構(gòu)建特定的頁(yè)面。

ISR 一般適用于符合 SSG 場(chǎng)景,但是卻對(duì)頁(yè)面的時(shí)限性有一定要求時(shí)。

如何實(shí)現(xiàn)

簡(jiǎn)單的 ISR 實(shí)現(xiàn)也很簡(jiǎn)單,只需要在收到頁(yè)面請(qǐng)求時(shí)按照更新策略判斷是否需要需要重新生成頁(yè)面,如果需要觸發(fā)頁(yè)面的構(gòu)建更新。需要注意一般情況下生成頁(yè)面不會(huì)影響頁(yè)面的響應(yīng),而是后臺(tái)去做構(gòu)建。

現(xiàn)在就基于之前寫的 SSG demo,做一下改造讓其支持 ISR。

修改構(gòu)建腳本

由于 ISR 構(gòu)建會(huì)同時(shí)在構(gòu)建腳本和服務(wù)器中觸發(fā),所以需要對(duì)之前的代碼做一些小小的改動(dòng)。

首先抽離出一個(gè)通用的構(gòu)建函數(shù)(由于服務(wù)器會(huì)使用到盡量避免同步代碼):

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={postInfo} />)}</div>`);
    }
}
export default build;

這樣就可以通過(guò) build 函數(shù)來(lái)構(gòu)建指定的 post 或者 list 頁(yè)面。

然后再將原先的構(gòu)建腳本做一下簡(jiǎn)單的修改:

import fs from 'fs';
import build from './build-util';
// make sure the dir exists
if (!fs.existsSync('dist')) {
    fs.mkdirSync('dist');
}
if (!fs.existsSync('dist/posts')) {
    fs.mkdirSync('dist/posts');
}
// get all the files in posts
const posts = fs.readdirSync('posts');
(async () => {
    for await (const post of posts) {
        await build('post', post.replace('.json', ''));
    }
    await build('list');
})();

服務(wù)器

由于 ISR 需要在請(qǐng)求時(shí)做是否構(gòu)建的判定,所以原先的靜態(tài)服務(wù)器方案無(wú)法繼續(xù)使用,我們換成 express 來(lái)實(shí)現(xiàn):

import express from 'express';
import path from 'path';
import fs from 'fs';
import build from '../build-util';
const app = express();
const expiresTime = 1000 * 60 * 10;
app.use(function (req, res, next) {
    setTimeout(() => {
        const filename = req.path.indexOf('.html') >= 0 ? req.path : req.path + 'index.html';
        // get the file's create timestamps
        fs.stat(path.join('./dist', filename), function (err, stats) {
            if (err) {
                console.error(err);
                return;
            }
            if (Date.now() - +stats.mtime > expiresTime) {
                console.log(filename, 'files expired, rebuilding...');
                if (filename === '/index.html') {
                    build('list');
                } else {
                    build('post', path.basename(filename).replace('.html', ''));
                }
            }
        });
    });
    next();
});
app.use(express.static('dist'));
app.listen(4000, () => {
    console.log('Listening on port 4000');
});

我們?cè)黾右粋€(gè) express 的中間件,讓其來(lái)判定文件是否過(guò)期,這里以十分鐘為例,實(shí)際場(chǎng)景可按需定義過(guò)期判定。這里過(guò)期后就會(huì)調(diào)用 build 文件來(lái)重新構(gòu)建該文件。要注意此處先返回再構(gòu)建,所以用戶不會(huì)等待構(gòu)建,并且此次訪問(wèn)依舊是舊的內(nèi)容,構(gòu)建完成后訪問(wèn)的才是新的內(nèi)容。

更多細(xì)節(jié)

  • 注意給構(gòu)建任務(wù)加鎖,避免一個(gè)頁(yè)面過(guò)期后多個(gè)請(qǐng)求同時(shí)觸發(fā)多個(gè)同樣的構(gòu)建任務(wù)
  • 給構(gòu)建任務(wù)加隊(duì)列,避免請(qǐng)求過(guò)多時(shí)同時(shí)出現(xiàn)過(guò)多的后臺(tái)構(gòu)建任務(wù)導(dǎo)致服務(wù)器資源問(wèn)題
  • 可以為每個(gè)文件制定特定的過(guò)期判定條件,比如 post 源文件的修改時(shí)間等等

總結(jié)

ISR 對(duì)比 SSG 可以有效的控制頁(yè)面的時(shí)效性,但也要付出額外的代價(jià):

  • 需要額外的開發(fā)成本
  • 需要額外的服務(wù)器資源投入
  • 無(wú)法使用一般的靜態(tài)文件服務(wù)器

沒(méi)有最佳,只有最適合,所以實(shí)際場(chǎng)景下還是按需選用。

本文的 demo 代碼放置在 React ISR Demo 中,可自行取閱。

以上就是詳解React ISR如何實(shí)現(xiàn) Demo的詳細(xì)內(nèi)容,更多關(guān)于React ISR實(shí)現(xiàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React Native模塊之Permissions權(quán)限申請(qǐng)的實(shí)例相機(jī)

    React Native模塊之Permissions權(quán)限申請(qǐng)的實(shí)例相機(jī)

    這篇文章主要介紹了React Native模塊之Permissions權(quán)限申請(qǐng)的實(shí)例相機(jī)的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例

    React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例

    本文主要介紹了React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • React Native使用fetch實(shí)現(xiàn)圖片上傳的示例代碼

    React Native使用fetch實(shí)現(xiàn)圖片上傳的示例代碼

    本篇文章主要介紹了React Native使用fetch實(shí)現(xiàn)圖片上傳的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • React Navigation 路由傳參的操作代碼

    React Navigation 路由傳參的操作代碼

    這篇文章主要介紹了React Navigation 路由傳參,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 教你在react中創(chuàng)建自定義hooks

    教你在react中創(chuàng)建自定義hooks

    簡(jiǎn)單來(lái)說(shuō)就是使用自定義hook可以將某些組件邏輯提取到可重用的函數(shù)中。 自定義hook是一個(gè)從use開始的調(diào)用其他hook的Javascript函數(shù),下面看下react中創(chuàng)建自定義hooks的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-11-11
  • 高性能React開發(fā)React Server Components詳解

    高性能React開發(fā)React Server Components詳解

    ReactServerComponents通過(guò)服務(wù)器端渲染、自動(dòng)代碼分割等技術(shù),實(shí)現(xiàn)了高性能的React開發(fā),它解決了客戶端數(shù)據(jù)請(qǐng)求鏈?zhǔn)窖舆t、敏感數(shù)據(jù)暴露風(fēng)險(xiǎn)等問(wèn)題,提供了更好的用戶體驗(yàn)和安全性,本文介紹高性能React開發(fā)React Server Components詳解,感興趣的朋友一起看看吧
    2025-03-03
  • React?UI組件庫(kù)之快速實(shí)現(xiàn)antd的按需引入和自定義主題

    React?UI組件庫(kù)之快速實(shí)現(xiàn)antd的按需引入和自定義主題

    react入門學(xué)習(xí)告一段路,下面這篇文章主要給大家介紹了關(guān)于React?UI組件庫(kù)之快速實(shí)現(xiàn)antd的按需引入和自定義主題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法

    ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法

    這篇文章主要為大家介紹了ahooks控制時(shí)機(jī)的hook實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 使用react-router4.0實(shí)現(xiàn)重定向和404功能的方法

    使用react-router4.0實(shí)現(xiàn)重定向和404功能的方法

    本篇文章主要介紹了使用react-router4.0實(shí)現(xiàn)重定向和404功能的方法,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • next-redux-wrapper使用細(xì)節(jié)及源碼分析

    next-redux-wrapper使用細(xì)節(jié)及源碼分析

    這篇文章主要為大家介紹了next-redux-wrapper使用細(xì)節(jié)及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評(píng)論