Nextjs ISR 企业落地实战

背景

Nextjs 项目本来使用的是 SSG 来渲染门户网站的 blog 的,目录如下:

这样技术实现是简单,但是维护成本比较高。运营和销售同学写完营销文章后,需要推送给研发,由研发录入到 git 仓库中,并且执行一遍发布流程。这样做,没有办法将文章撰写作为一个独立的营销任务,必须借助技术发布。而且还有个问题,blog 越来越多,放在仓库里,会导致仓库大小越来越大:

需求与技术方案设计

于是我们就设计了一个这样的内部需求:

维护一个内部的 blog 发布平台,运营录入后点击发布,同时通知 Nextjs 项目触发更新文章。

技术方案:

  • 内部 blog 发布平台使用 antd + go 搭建,负责录入文章到数据库,并提供公网接口获取
  • Nextjs 改造为通过接口获取动态数据,设置缓存来优化访问;并暴露 API,内部 blog 发布平台触发更新后清除缓存,用户下次访问就回去拉取最新的数据源。

初步实现

内部 blog 发布平台

没啥说的,普通的后台管理系统,如图

md 编辑器就使用掘金的 bytemd

用户录入后,存入到数据库中,并暴露接口来获取。

Nextjs 项目改造

页面配置:

js 复制代码
export const dynamic = 'auto'; // 允许页面缓存
export const dynamicParams = true;
export const revalidate = 259200; // 页面缓存 3 天(与 fetch 缓存时间一致)

将读取静态目录换为通过接口(自己开发 API 提供数据源)获取:

js 复制代码
// SSR 页面
const postData = {
  Action: "GetPublishedArticleList",
  Lang: lng,
};

const startTime = Date.now();
const res = await fetch(blogApiUrl, {
  method: "POST",
  headers: {
    'remote_user': 'admin',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(postData),
  // 设置缓存:有效期3天(259200秒),使用标签以便外部API可以清除缓存
  next: {
    revalidate: 259200, // 3天
    tags: [`blog-list-${lng}`],
  },
});

// 拿到数据后处理
if (res.ok) {
    const response = await res.json();
    const count = response?.Data?.Total || 0;
    ...
}

...

然后暴露 API,负责清除 fetch 缓存:

该 API 要记得配置 cors 跨域和来源 ip 和频次限制。

此外,需要配置 api 请求拦截,避免被中间件等影响造成请求不到地址:

js 复制代码
async headers() {
    return [
      {
        // 排除 /api 路径,让 API 路由自己处理 CORS
        source: "/((?!api).)*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // Set your origin
          },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET, POST, PUT, DELETE, OPTIONS",
          },
          {
            key: "Access-Control-Allow-Headers",
            value: "Content-Type, Authorization",
          },
        ],
      },
    ];
  },

ISR 工作流程

首次访问:

  • 服务端渲染(SSR), fetch 缓存
  • 生成 HTML 并缓存
  • 返回给用户

后续访问(3 天内):

  • 直接返回缓存的 HTML, 不重新渲染, 响应快

3 天后:

  • 第一个请求触发后台重新渲染
  • 更新全部缓存
  • 后续请求使用新缓存

调用 /api/revalidate-blog:

  • 立即清除缓存
  • 下次访问重新渲染

落地演示

新建一篇文章,点击发布,更新状态:

调用 revalidate API 触发缓存更新:

线上刷新查看:

成功!!

相关推荐
大萝卜呼呼5 天前
Next.js第八课 - 缓存机制
前端·next.js
竹林8186 天前
在Next.js NFT市场中,我如何解决动态路由、链上数据获取与状态同步的连环坑
前端·javascript·next.js
大萝卜呼呼10 天前
Next.js第三课 - 布局与页面 - 优栈
前端·next.js
大萝卜呼呼11 天前
Next.js第二课 - 项目结构详解 - 优栈
前端·next.js
前端缘梦12 天前
Next.js全栈项目部署全流程|从0到1解决数据库、WebSocket、图片上传所有坑
前端·全栈·next.js
Bigger12 天前
🚀 开源发布!从 0 到 1,使用 Next.js + Nest.js 构建全栈自动化数据分析 AI Agent
agent·nestjs·next.js
倾颜12 天前
我是怎么把 Multi-Tool Runtime 升级成第一层 Skill Runtime 的
前端·llm·next.js
倾颜17 天前
不只是接个计算器:我是怎么把 Tool Calling 做成可扩展骨架的
langchain·llm·next.js
倾颜21 天前
我把本地 AI Chat 项目重构了一遍:用 LangChain.js + Ollama + Streamdown 搭了一个最小可扩展架构
langchain·llm·next.js
helloweilei21 天前
React.cache:让你的服务器组件告别“重复劳动”
next.js