next.js中实现缓存

🧩 一、缓存的核心思路 在 Fastify + Next.js 场景下,缓存通常分为三层:

缓存层级 缓存内容 适用场景
1. HTTP Header 缓存(浏览器/CDN 层) 静态资源、HTML 页面 CDN 前置缓存、浏览器缓存控制
2. 内存缓存(进程内) 接口数据、配置、语言包、皮肤数据 小规模、高并发场景下的快速命中
3. 外部缓存(Redis 等) 登录态、用户信息、接口响应 分布式服务场景,多节点共享

⚙️ 二、典型应用场景

✅ 常见你在自定义 Fastify 服务器中会缓存的内容包括:

  • /fePublicInfo 这样的公共接口(语言包、皮肤配置)
  • 登录用户的简要信息(token→user)
  • SSR 数据预加载(例如首页接口)
  • 远程配置文件、CDN JSON 等

🧠 三、Fastify 缓存的常用实现方式

方式一 :使用内存缓存(最简单) 使用 Maplru-cache 作为本地缓存。

✅ 示例:缓存 /fePublicInfo 响应 10 分钟

kotlin 复制代码
import Fastify from 'fastify'
import LRU from 'lru-cache'

const fastify = Fastify()
const cache = new LRU({
  max: 100,           // 最多缓存 100 条
  ttl: 1000 * 60 * 10 // 缓存 10 分钟
})

fastify.get('/api/fePublicInfo', async (req, reply) => {
  const cacheKey = 'fePublicInfo'
  const cached = cache.get(cacheKey)

  if (cached) {
    // 命中缓存
    reply.header('x-cache', 'HIT')
    return cached
  }

  // 缓存未命中 → 请求远程服务
  const res = await fetch('https://api.xxx.com/fePublicInfo')
  const data = await res.json()

  // 写入缓存
  cache.set(cacheKey, data)
  reply.header('x-cache', 'MISS')
  return data
})

fastify.listen({ port: 3000 })

🔹 优点:超简单、适合小规模服务

🔹 缺点:内存缓存无法跨进程共享,适合单实例部署

方式二:使用 Redis 缓存(推荐生产环境) ✅ 示例:基于 Redis 缓存 API 响应

javascript 复制代码
import Fastify from 'fastify'
import Redis from '@fastify/redis'

const fastify = Fastify()

fastify.register(Redis, { host: '127.0.0.1', port: 6379 })

fastify.get('/api/fePublicInfo', async (req, reply) => {
  const cacheKey = 'fePublicInfo'
  const cached = await fastify.redis.get(cacheKey)

  if (cached) {
    reply.header('x-cache', 'HIT')
    return JSON.parse(cached)
  }

  const res = await fetch('https://api.xxx.com/fePublicInfo')
  const data = await res.json()

  // 缓存 10 分钟
  await fastify.redis.set(cacheKey, JSON.stringify(data), 'EX', 60 * 10)
  reply.header('x-cache', 'MISS')
  return data
})

🔹 优点:跨实例共享、持久化、可限流

🔹 缺点:多一次网络开销

方式三:对 SSR 页面做缓存(全页缓存) 适用于不经常变化的 SSR 页面,比如首页或营销页。

✅ 示例:缓存 SSR 渲染结果

javascript 复制代码
import Fastify from 'fastify'
import LRU from 'lru-cache'
import next from 'next'

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const fastify = Fastify()
const pageCache = new LRU({ max: 100, ttl: 1000 * 60 * 5 }) // 5分钟缓存

fastify.get('/', async (req, reply) => {
  const cacheKey = 'page:/'

  if (pageCache.has(cacheKey)) {
    reply.header('x-cache', 'HIT').type('text/html')
    return reply.send(pageCache.get(cacheKey))
  }

  const html = await app.renderToHTML(req.raw, reply.raw, '/', req.query)
  pageCache.set(cacheKey, html)

  reply.header('x-cache', 'MISS').type('text/html')
  reply.send(html)
})

fastify.all('*', (req, reply) => handle(req.raw, reply.raw))

🔹 优点:显著提升 SSR 页面性能

🔹 缺点:要注意缓存失效逻辑(如语言切换、登录态)

方式四:利用 HTTP 缓存头(CDN + 浏览器)

rust 复制代码
reply.header('Cache-Control', 'public, max-age=300, stale-while-revalidate=60')

这告诉 CDN/浏览器:

  • 正常缓存 300 秒;
  • 超时后可继续用旧缓存 60 秒,同时异步更新。

综合最佳实践 在中大型项目中,推荐组合策略:

层级 缓存内容 技术
CDN 层 图片、静态资源 Cache-Control
Fastify 层 公共接口 Redis / LRU
SSR 层 页面 HTML LRU / Redis
客户端层 用户操作数据 localStorage / SW
  • 静态资源通过 CDN + Cache-Control 头;

  • 接口数据通过 Fastify 插件(LRU 或 Redis)缓存;

  • SSR 页面通过 LRU 做全页缓存;

  • 并结合 stale-while-revalidate 策略提升实时性。

    这样既保证了性能,也避免缓存击穿问题。

相关推荐
C_心欲无痕20 分钟前
nginx - 核心概念
运维·前端·nginx
开开心心_Every24 分钟前
安卓做菜APP:家常菜谱详细步骤无广简洁
服务器·前端·python·学习·edge·django·powerpoint
前端_Danny26 分钟前
用 ECharts markLine 实现节假日标注
前端·信息可视化·echarts
古城小栈28 分钟前
Rust 丰富&好用的 格式化语法
前端·算法·rust
丢,捞仔38 分钟前
uni-app上架应用添加权限提示框
前端·javascript·uni-app
Glink44 分钟前
从零开始编写自己的AI账单Agent
前端·agent·ai编程
Hilaku44 分钟前
我是如何用一行 JS 代码,让你的浏览器内存瞬间崩溃的?
前端·javascript·node.js
努力犯错玩AI44 分钟前
如何在ComfyUI中使用Qwen-Image-Layered GGUF:完整安装和使用指南
前端·人工智能
Lefan1 小时前
在浏览器中运行大模型:基于 WebGPU 的本地 LLM 应用深度解析
前端
五仁火烧1 小时前
npm run build命令详解
前端·vue.js·npm·node.js