Learning
Next.js

Caching és a Next.js 16 új cache modell

Ez a Next.js 16 legjelentősebb változása. Az implicit, 'magic' caching helyett explicit, fejlesztő által kontrollált cache modell lépett éle

9. Caching és a Next.js 16 új cache modell

Ez a Next.js 16 legjelentősebb változása. Az implicit, "magic" caching helyett explicit, fejlesztő által kontrollált cache modell lépett életbe.

A korábbi modell problémái

A Next.js 13-14-ben a fetch() hívások alapértelmezetten cache-elve voltak, ami sok fejlesztőt megzavart:

  • Nem volt egyértelmű, mi van cache-elve és mi nem
  • Nehéz volt debuggolni, miért nem frissül az adat
  • A viselkedés "meglepetéseket" okozott production környezetben

Next.js 16: Opt-in caching

Alapelv: minden dinamikusan fut le, hacsak te nem mondod meg, hogy cache-eljük.

// app/products/page.tsx
// Alapértelmezett: NEM cache-elt, minden kérésnél lefut
export default async function ProductsPage() {
  const products = await fetchProducts()
  return <ProductList products={products} />
}

"use cache" direktíva

A "use cache" az explicit cache jelzés – oldal, komponens vagy függvény szintjén:

// Teljes oldal cache-elése
'use cache'

export default async function BlogPage() {
  const posts = await fetchPosts()
  return <BlogList posts={posts} />
}
// Függvény szintű cache
async function getExpensiveData() {
  'use cache'
  const data = await db.analytics.aggregate()
  return data
}
// Komponens szintű cache
async function CachedProductList() {
  'use cache'
  const products = await fetchProducts()
  return <ProductList products={products} />
}

cacheLife – cache élettartam beállítása

import { cacheLife } from 'next/cache'

async function getNewsArticles() {
  'use cache'
  cacheLife('hours') // beépített profilok: seconds, minutes, hours, days, weeks, max

  const articles = await fetchNews()
  return articles
}

Egyedi cacheLife konfiguráció:

// next.config.ts
const nextConfig = {
  experimental: {
    cacheLife: {
      products: {
        stale: 60 * 5,      // 5 perc – stale-while-revalidate ablak
        revalidate: 60 * 60, // 1 óra – szerver oldali revalidálás
        expire: 60 * 60 * 24, // 24 óra – maximális élettartam
      },
    },
  },
}
async function getProducts() {
  'use cache'
  cacheLife('products') // egyedi profil használata
  return await db.products.findAll()
}

cacheTag – tag alapú invalidálás

import { cacheTag } from 'next/cache'

async function getPost(slug: string) {
  'use cache'
  cacheTag('posts', `post-${slug}`) // több tag is megadható

  return await db.posts.findOne({ slug })
}

revalidateTag és updateTag

'use server'

import { revalidateTag, updateTag } from 'next/cache'

// Teljes tag invalidálása (régi adat eldobása)
export async function deletePost(id: string) {
  await db.posts.delete(id)
  revalidateTag('posts') // minden 'posts' tag-gel rendelkező cache törlése
}

// Tag frissítése új értékkel (finomabb kontroll)
export async function updatePost(id: string, data: PostData) {
  await db.posts.update(id, data)
  updateTag(`post-${id}`) // csak az adott post cache-ének frissítése
}

refresh – router frissítése

'use server'

import { refresh } from 'next/cache'

export async function markNotificationRead(id: string) {
  await db.notifications.markRead(id)
  refresh() // kliens router frissítése Server Action-ből
}

Partial Pre-Rendering (PPR) és Cache Components

A Next.js 16 "Cache Components" modell teljesíti a PPR ígéretét: ugyanazon az URL-en egyszerre lehet statikus és dinamikus tartalom.

// app/product/[id]/page.tsx
import { Suspense } from 'react'

// Ez a komponens cache-elt (statikus)
async function CachedProductInfo({ id }: { id: string }) {
  'use cache'
  cacheLife('days')
  const product = await fetchProduct(id)
  return <ProductDetails product={product} />
}

// Ez a komponens dinamikus (felhasználó-specifikus)
async function UserSpecificPrice({ id }: { id: string }) {
  const price = await fetchPersonalizedPrice(id) // nem cache-elt
  return <PriceDisplay price={price} />
}

export default async function ProductPage({ params }) {
  const { id } = await params
  return (
    <div>
      <Suspense fallback={<ProductSkeleton />}>
        <CachedProductInfo id={id} />  {/* Azonnal megjelenik cache-ből */}
      </Suspense>
      <Suspense fallback={<PriceSkeleton />}>
        <UserSpecificPrice id={id} />   {/* Dinamikusan töltődik */}
      </Suspense>
    </div>
  )
}

Cache összehasonlítás: Next.js 14 vs 16

Next.js 14Next.js 16
AlapértelmezésImplicit cacheDinamikus (no cache)
Cache jelzésAutomatikus"use cache" direktíva
MeglepetésekSokNincsenek
GranularitásOldal/fetch szintűKomponens/függvény szintű
DebuggolhatóságNehézEgyértelmű

📝 Összefoglaló – 9. fejezet

  • A Next.js 16 explicit opt-in cache modellre váltott – alapból minden dinamikus
  • A "use cache" direktíva oldal, komponens vagy függvény szinten engedélyezi a cache-t
  • cacheLife és cacheTag finomhangolják a lejárati időt és az invalidálást
  • revalidateTag és updateTag Server Action-ökből triggereli a cache frissítést
  • A PPR és Cache Components együtt teszik lehetővé az "instant navigation" élményt

On this page