緩存策略(Cache Strategies)

友情提示:光敏性癲癇患者請勿觀看!!!

緩存策略分兩種:

未啓用緩存組件:

確保cacheComponents配置為false或者不配置。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  cacheComponents: false, // 緩存組件(關閉或者不配置)
};

export default nextConfig;

src/app/home/page.tsx(新建一個頁面)

export default async  function Home() {
    const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json') //這個接口隨機返回一個二刺猿圖片
    const data = await randomImage.json()
    console.log(data)
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.url} alt="random image" />
        </div>
    )
}


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

我們可以看到上圖在開發模式是沒有任何問題的,每次刷新圖片都會重新獲取。

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

但是當我們進行構建之後npm run build && npm run start我們發現每次刷新圖片都不會變化,始終是同一個圖片。

原因是:Next.js會盡可能多的進行緩存,以提高性能降低成本,這意味着路由會被靜態渲染,以及數據請求也會被緩存,除非禁用緩存。

Next.js第十四章(緩存策略)_獲取數據_03

我們觀察上圖可以發現有兩個符號:

  • (空心圓): 表示這是預渲染的靜態內容。
  • ƒ(f函數符): 表示這是動態內容。

那麼如何退出緩存呢?

第一種方案重新驗證

使用revalidate屬性,可以設置緩存時間,單位為秒。

export const revalidate = 5 // 5秒後重新更新
//export const revalidate = 0 // 設置為0表示不緩存
export default async  function Home() {
    const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.url} alt="random image" />
        </div>
    )
}

Next.js第十四章(緩存策略)_緩存_04

當我們重新運行之後,每過5秒,圖片會重新獲取,並且會顯示新的圖片。

第二種方案使用dynamic屬性

使用dynamic屬性,並且設置為force-dynamic,表示將禁用緩存,每次請求都會重新獲取數據。

export const dynamic = 'force-dynamic' // 動態更新 緩存組件不需要使用這個 默認都是動態內容
export default async  function Home() {
    const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.url} alt="random image" />
        </div>
    )
}

Next.js第十四章(緩存策略)_前端_05

第三種方案使用禁用緩存

使用cache屬性,並且設置為no-store,表示將禁用緩存,每次請求都會重新獲取數據。

export default async  function Home() {
    const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json',{cache:'no-store'})
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.url} alt="random image" />
        </div>
    )
}
第四種方案使用任意動態內容API

當你使用以下任意API時,該路由會被視為動態內容,不會被緩存。

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

export default async  function Home() {
    await connection()
    const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json')
    const data = await randomImage.json()
    return (
        <div>
            <h1>Home</h1>
            <img width={500} height={500} src={data.url} alt="random image" />
        </div>
    )
}

啓用緩存組件:

確保cacheComponents配置為true

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  cacheComponents: true, //開啓緩存組件
};

export default nextConfig;

啓用緩存組件之後,所有組件默認為動態內容,因此export const dynamic = 'force-dynamic'不需要配置。

import { Suspense } from "react"
const DynamicImage = async () => {
  const randomImage = await fetch('https://www.loliapi.com/acg/pc?type=json')
  const data = await randomImage.json()
  return (
    <img width={500} height={500} src={data.url} alt="random image" />
  )
}

export default async  function Home() {

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

Next.js第十四章(緩存策略)_獲取數據_06

然後你會發現多了一個符號

  • (部分預渲染): 表示頁面預渲染為靜態 HTML,同時包含動態服務器流式傳輸的內容。