緩存策略(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>
)
}
我們可以看到上圖在開發模式是沒有任何問題的,每次刷新圖片都會重新獲取。
但是當我們進行構建之後npm run build && npm run start我們發現每次刷新圖片都不會變化,始終是同一個圖片。
原因是:Next.js會盡可能多的進行緩存,以提高性能降低成本,這意味着路由會被靜態渲染,以及數據請求也會被緩存,除非禁用緩存。
我們觀察上圖可以發現有兩個符號:
○(空心圓): 表示這是預渲染的靜態內容。ƒ(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>
)
}
當我們重新運行之後,每過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>
)
}
第三種方案使用禁用緩存
使用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>
)
}
然後你會發現多了一個符號
◐(部分預渲染): 表示頁面預渲染為靜態 HTML,同時包含動態服務器流式傳輸的內容。