Next.js第十四章(缓存策略)

缓存策略(Cache Strategies)

友情提示:光敏性癫痫患者请勿观看!!!

缓存策略分两种:

未启用缓存组件:

确保cacheComponents配置为false或者不配置。

ts 复制代码
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  cacheComponents: false, // 缓存组件(关闭或者不配置)
};

export default nextConfig;

src/app/home/page.tsx(新建一个页面)

tsx 复制代码
export default async  function Home() {
    const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json') //这个接口随机返回一个二刺猿图片
    const data = await randomImage.json()
    console.log(data)
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.imgurl} alt="random image" />
        </div>
    )
}

我们可以看到上图在开发模式是没有任何问题的,每次刷新图片都会重新获取。

但是当我们进行构建之后npm run build && npm run start我们发现每次刷新图片都不会变化,始终是同一个图片。

原因是:Next.js会尽可能多的进行缓存,以提高性能降低成本,这意味着路由会被静态渲染,以及数据请求也会被缓存,除非禁用缓存。

我们观察上图可以发现有两个符号:

  • (空心圆): 表示这是预渲染的静态内容。
  • ƒ(f函数符): 表示这是动态内容。

那么如何退出缓存呢?

第一种方案重新验证

使用revalidate属性,可以设置缓存时间,单位为秒。

tsx 复制代码
export const revalidate = 5 // 5秒后重新更新
//export const revalidate = 0 // 设置为0表示不缓存
export default async  function Home() {
    const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.imgurl} alt="random image" />
        </div>
    )
}

当我们重新运行之后,每过5秒,图片会重新获取,并且会显示新的图片。

第二种方案使用dynamic属性

使用dynamic属性,并且设置为force-dynamic,表示将禁用缓存,每次请求都会重新获取数据。

tsx 复制代码
export const dynamic = 'force-dynamic' // 动态更新 缓存组件不需要使用这个 默认都是动态内容
export default async  function Home() {
    const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.imgurl} alt="random image" />
        </div>
    )
}
第三种方案使用禁用缓存

使用cache属性,并且设置为no-store,表示将禁用缓存,每次请求都会重新获取数据。

tsx 复制代码
export default async  function Home() {
    const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json',{cache:'no-store'})
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.imgurl} alt="random image" />
        </div>
    )
}
第四种方案使用任意动态内容API

当你使用以下任意API时,该路由会被视为动态内容,不会被缓存。

  • cookies
  • headers
  • connection
  • searchParams
  • fetch和{ cache: 'no-store' }
tsx 复制代码
import { connection } from "next/server"

export default async  function Home() {
    await connection()
    const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.imgurl} alt="random image" />
        </div>
    )
}

启用缓存组件:

确保cacheComponents配置为true

ts 复制代码
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  cacheComponents: true, //开启缓存组件
};

export default nextConfig;

启用缓存组件之后,所有组件默认为动态内容,因此export const dynamic = 'force-dynamic'不需要配置。

tsx 复制代码
import { Suspense } from "react"
const DynamicImage = async () => {
  const randomImage = await fetch('https://www.dmoe.cc/random.php?return=json')
  const data = await randomImage.json()
  return (
    <img width={500} height={500} src={data.imgurl} alt="random image" />
  )
}

export default async  function Home() {

    return (
        <div>
            <h1>Home</h1>
            <Suspense fallback={<div>Loading...</div>}>
                <DynamicImage />
            </Suspense>
        </div>
    )
}

然后你会发现多了一个符号

  • (部分预渲染): 表示页面预渲染为静态 HTML,同时包含动态服务器流式传输的内容。
相关推荐
Sherotree20 分钟前
Google Antigravity——Agent 被提到主界面
前端·ide·后端·edge浏览器
里欧跑得慢1 小时前
Flutter 像素级还原:设计稿到代码的视觉无损转换技巧
前端·css·flutter·web
里欧跑得慢1 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
苏灿烤鱼2 小时前
没有机密文件,也没有付费数据,在浏览器里造一颗"间谍卫星"
前端·javascript·github
泯泷2 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法
泯泷2 小时前
手搓JSVM第 3 篇:从栈式 VM 到寄存器式 VM:为什么我们选择寄存器
前端·javascript·算法
泯泷2 小时前
第 4 篇:让 VM 支持变量:Slot、Environment 与 TDZ
前端·javascript·算法
粥里有勺糖4 小时前
视野修炼-技术周刊第131期 | Bun 与 pnpm Rust 化
前端·github·agent