Cache: 'use cache', tag-uri și PPR
Cache Components, cacheLife, cacheTag, updateTag vs revalidateTag.
Actualizat
Ce este cache-ul
Cache = păstrezi rezultatul unei operații costisitoare (query în DB, request la API, randare) ca să nu o refaci la fiecare cerere. Rezultatul: pagini instantanee și mai puțină încărcare pe server.
Prețul: datele din cache se pot învechi. De aceea orice cache are nevoie de o strategie de invalidare — când arunci copia veche.
Cache Components (Next 16)
Modelul din Next 16, activat în next.config.ts:
const nextConfig = { cacheComponents: true, partialPrefetching: true }Regula: nimic nu e cache-uit implicit. Tu marchezi explicit ce se cache-uiește, cu directiva 'use cache'.
'use cache'
import { cacheLife, cacheTag } from 'next/cache'
export async function getPosts() {
'use cache'
cacheLife('hours') // cât trăiește
cacheTag('posts') // etichetă pentru invalidare
return db.post.findMany()
}- Argumentele funcției intră automat în cheia de cache:
getPost(1)șigetPost(2)sunt intrări separate. - Se pune pe funcții de date, pe componente sau pe o pagină întreagă.
- Nu poți citi
cookies()/headers()înăuntru — le citești afară și trimiți valoarea ca argument.
Profilurile cacheLife
| Profil | Revalidare | Expirare | Pentru |
|---|---|---|---|
seconds |
1s | 1 min | aproape live (devine dinamic) |
minutes |
1 min | 1 h | feed-uri, prețuri |
hours |
1 h | 1 zi | conținut editorial (lecțiile de aici) |
days |
1 zi | 1 săpt. | pagini care se schimbă rar |
max |
30 zile | 1 an | aproape static |
Ce este Partial Prerendering
PPR combină static și dinamic în aceeași pagină:
- La build, Next randează tot ce poate (inclusiv ce e în
'use cache') → static shell, servit instant de pe CDN. - Părțile dinamice (în
<Suspense>, care citesc cookies etc.) sunt randate la request și transmise în stream.
Exact aplicația asta: lecția e în static shell; progresul tău (din cookie) vine în stream.
Output-ul npm run build arată tipul fiecărei rute: ○ static, ◐ partial prerender, ƒ dinamic.
Invalidare — tipuri și când
| Funcție | Unde | Comportament | Când |
|---|---|---|---|
updateTag('posts') |
doar Server Actions | expiră imediat; următorul request așteaptă date noi | userul a modificat ceva și trebuie să vadă imediat (read-your-own-writes) |
revalidateTag('posts', 'max') |
Server Actions + Route Handlers | stale-while-revalidate: servește vechiul, reîmprospătează în fundal | conținut din CMS / webhook — o mică întârziere e ok |
revalidatePath('/blog') |
idem | invalidează o rută întreagă | nu ai tag-uri potrivite |
refresh() |
Server Actions | re-cere datele dinamice ale paginii curente | după mutații fără cache tag (ca salvarea progresului de aici) |
Pe scurt
- Nimic nu e cache-uit implicit;
'use cache'+cacheLife+cacheTagexplicit. - PPR = static shell instant + părți dinamice în stream.
updateTagpentru userul care tocmai a modificat;revalidateTag(tag, 'max')pentru restul.