最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解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 說在 ISR 如何實(shí)現(xiàn)。

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

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

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

簡單的 ISR 實(shí)現(xiàn)也很簡單,只需要在收到頁面請(qǐng)求時(shí)按照更新策略判斷是否需要需要重新生成頁面,如果需要觸發(fā)頁面的構(gòu)建更新。需要注意一般情況下生成頁面不會(huì)影響頁面的響應(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;

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

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

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ù)器方案無法繼續(xù)使用,我們換成 express 來實(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 的中間件,讓其來判定文件是否過期,這里以十分鐘為例,實(shí)際場(chǎng)景可按需定義過期判定。這里過期后就會(huì)調(diào)用 build 文件來重新構(gòu)建該文件。要注意此處先返回再構(gòu)建,所以用戶不會(huì)等待構(gòu)建,并且此次訪問依舊是舊的內(nèi)容,構(gòu)建完成后訪問的才是新的內(nèi)容。

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

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

總結(jié)

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

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

沒有最佳,只有最適合,所以實(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中遍歷數(shù)組生成標(biāo)簽問題

    React中遍歷數(shù)組生成標(biāo)簽問題

    這篇文章主要介紹了React中遍歷數(shù)組生成標(biāo)簽問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • React?Redux管理庫示例詳解

    React?Redux管理庫示例詳解

    這篇文章主要介紹了如何在React中直接使用Redux,目前redux在react中使用是最多的,所以我們需要將之前編寫的redux代碼,融入到react當(dāng)中去,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2022-12-12
  • React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法

    React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法

    這篇文章主要介紹了React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法,文中通過代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-09-09
  • React并發(fā)更新與性能優(yōu)化解析

    React并發(fā)更新與性能優(yōu)化解析

    這篇文章主要為大家介紹了React并發(fā)更新與性能優(yōu)化解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • React useCallback使用教程

    React useCallback使用教程

    useCallback是react中比較重要的一個(gè)hook,useCallback 用來返回一個(gè)函數(shù),在父子組件傳參或者通用函數(shù)封裝中,起到舉足輕重的作用
    2023-01-01
  • react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果

    react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果

    本篇文章通過完整的代碼給大家介紹了react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-01-01
  • React.js綁定this的5種方法(小結(jié))

    React.js綁定this的5種方法(小結(jié))

    this在javascript中已經(jīng)相當(dāng)靈活,這篇文章主要介紹了React.js綁定this的5種方法(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • React onBlur回調(diào)中使用document.activeElement返回body完美解決方案

    React onBlur回調(diào)中使用document.activeElement返回body完美解決方案

    這篇文章主要介紹了React onBlur回調(diào)中使用document.activeElement返回body完美解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • react新版本生命周期鉤子函數(shù)及用法詳解

    react新版本生命周期鉤子函數(shù)及用法詳解

    這篇文章主要介紹了react新版本生命周期鉤子函數(shù)及用法詳解,本文通過示例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    這篇文章主要介紹了詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01

最新評(píng)論

闽侯县| 珠海市| 延安市| 八宿县| 浦北县| 凤凰县| 太和县| 沅陵县| 汝州市| 滦南县| 循化| 江都市| 宁城县| 洛阳市| 中阳县| 六安市| 延吉市| 察雅县| 湄潭县| 水富县| 金塔县| 邵武市| 新野县| 仁寿县| 自治县| 丰宁| 凤城市| 铜鼓县| 伊春市| 左权县| 沙雅县| 无棣县| 玉树县| 华池县| 繁昌县| 宣武区| 安仁县| 浦北县| 志丹县| 黄浦区| 利川市|