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 触发缓存更新:

线上刷新查看:

成功!!

相关推荐
倾颜20 小时前
给 AI Chat 加上长期记忆:模型提取 + 程序把关 + 规则召回
llm·agent·next.js
倾颜1 天前
AI Mind 的多会话短期记忆容器:如何隔离多个聊天上下文
langchain·agent·next.js
倾颜1 天前
Agent-as-Tool:从硬编码工作流到受控并行多Agent的一次实践
langchain·next.js
倾颜2 天前
给受控 Agent 接入 LangSmith:如何观测 HITL / Resume 生命周期
langchain·next.js
薛定喵的谔10 天前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js
Flynt10 天前
我的Next.js项目升级到16之后,dev倒是快了,但build差点让我回退
react.js·next.js·turbopack
Patrick_Wilson13 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
疯狂SQL16 天前
手写高性能在线 JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
typescript·json·next.js·web worker·前端性能优化·esbuild·源码实战
不知疲倦的老鸟16 天前
Node.js 库在浏览器里跑不了的教训
react.js·next.js
倾颜22 天前
从本地 Ollama 到线上多模型 Runtime:接入 DeepSeek / Qwen 的实战复盘
langchain·next.js·deepseek