ข้ามไปยังเนื้อหา

use cache และ Cache Components

Cache Components พลิกโมเดล แทนที่จะจำ cache option ต่อ fetch เรา mark function, file หรือ component ด้วย directive 'use cache' เพื่อบอกว่า “cache อันนี้” แล้วปรับ lifetime กับ invalidation ด้วย cacheLife และ cacheTag

ใส่ string 'use cache' ไว้บนสุดของ function หรือ file แล้วทุกอย่างที่ function นั้น return จะถูก cache ไม่ว่าจะเป็น fetch, query database หรือทั้ง component ที่ render แล้ว วิธีนี้มาแทนการโปรย cache option ตาม call ทีละอัน

lib/data.ts
import { cacheLife, cacheTag } from 'next/cache'
async function getData() {
'use cache'
cacheLife('hours')
cacheTag('data')
const res = await fetch('https://api.example.com/data')
return res.json()
}

cacheLife ตั้งว่า entry จะสดอยู่นานแค่ไหน เป็น named profile อย่าง 'hours' หรือ object ที่ระบุชัด cacheTag ติด tag เพื่อให้ revalidateTag ตัวเดิมที่เรารู้จักอยู่แล้ว invalidate entry นั้นได้แบบ on-demand

import { cacheLife, cacheTag } from 'next/cache'
async function getProduct(id: string) {
'use cache'
cacheTag(`product-${id}`)
cacheLife({ stale: 60, revalidate: 300 })
return db.product.findUnique({ where: { id } })
}

'use cache' ต้องใช้ flag cacheComponents ใน Next.js 16 flag ตัวเดียวกันนี้ ยัง เป็นวิธีเปิด Partial Prerendering ด้วย flag ppr แบบ experimental เดิมและ export experimental_ppr ถูกถอดออกไปแล้ว เมื่อเปิด flag นี้ Next.js จะ prerender shell แบบ static และ stream ส่วน dynamic ที่ไม่ cache เข้ามาตอน request

next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig

มีสอง variant ที่ต่อยอดโมเดลนี้ 'use cache: private' cache ต่อ user และอ่าน cookies() ได้ จึงไม่แชร์ข้ามผู้เข้าชม ส่วน 'use cache: remote' เก็บใน shared cache ฝั่ง server ที่แชร์ข้าม user ทั้งสองใช้ได้ในปัจจุบันแต่ยัง stabilizing ดังนั้น pin version ของ Next.js และเช็ค docs อีกครั้งก่อนพึ่งชื่อที่แน่นอน

import { cacheLife } from 'next/cache'
import { cookies } from 'next/headers'
async function getRecommendations() {
'use cache: private'
cacheLife({ stale: 60 })
const sessionId = (await cookies()).get('session-id')?.value
return db.recommendations.forSession(sessionId)
}
flowchart TD
  A["cacheComponents: true"] --> B["'use cache' function or component"]
  A --> C["Partial Prerendering"]
  B --> D["Cached static shell"]
  C --> D
  D --> E["Dynamic uncached holes stream in"]
cacheComponents: the static shell plus streamed dynamic holes
directive use cache ทำอะไร?
flag ตัวไหนเปิดใช้ use cache?
อะไรตั้ง lifetime และ tag ของ entry use cache?
ใน Next.js 16 cacheComponents ยังเปิดอะไรอีก?