Guía práctica de Cache Components y la directiva "use cache" en Next.js 16

Cache Components cambia el modelo mental del cacheo en Next.js: en vez de heurísticas implícitas, marcas explícitamente con "use cache" qué partes de tu app pueden cachearse.


Hasta Next.js 15, el cacheo de fetch funcionaba por heurísticas implícitas: por defecto se cacheaba, salvo que algo (una cookie, un fetch con no-store, ciertas APIs dinámicas) marcara la ruta entera como dinámica. Funcionaba, pero era difícil predecir qué se cacheaba con solo mirar el código. Cache Components en Next.js 16 invierte el modelo: nada se cachea a menos que lo marques explícitamente con la directiva "use cache".

El modelo antiguo: heurísticas implícitas

// Next.js 15: ¿esto se cachea? Depende de qué haga el resto de la ruta
async function Stats() {
  const res = await fetch('https://api.example.com/stats');
  return <p>{(await res.json()).visits} visitas</p>;
}

Si en algún otro punto de la misma ruta usabas cookies() o headers(), toda la ruta pasaba a ser dinámica y este fetch dejaba de cachearse, sin que hubiera ninguna señal visual en este componente de que eso estaba pasando.

El modelo nuevo: cacheo explícito

Marcas con "use cache" la función, componente o archivo que quieres que sea cacheable. Todo lo demás es dinámico por defecto.

// Next.js 16: explícito
async function Stats() {
  'use cache';
  const res = await fetch('https://api.example.com/stats');
  return <p>{(await res.json()).visits} visitas</p>;
}

Ese Stats se cachea independientemente de lo que haga el resto de la página. Puedes tener una ruta con partes estáticas cacheadas y partes dinámicas (que leen cookies, por ejemplo) conviviendo, sin que una arrastre a la otra.

Control fino: tags y tiempo de vida

Dos funciones nuevas para gestionar la caché desde dentro del componente:

import { cacheTag, cacheLife } from 'next/cache';

async function ProductPrice({ id }: { id: string }) {
  'use cache';
  cacheTag(`product-${id}`);
  cacheLife('hours');

  const res = await fetch(`https://api.example.com/products/${id}`);
  return <span>{(await res.json()).price} €</span>;
}

A nivel de archivo

Si toda una ruta o layout es esencialmente estático, puedes poner la directiva al principio del archivo en vez de en cada función:

// app/blog/page.tsx
'use cache';

export default async function BlogPage() {
  const posts = await fetchBlog();
  return <PostList posts={posts} />;
}

Relación con Partial Prerendering

Cache Components es la pieza que hace útil a Partial Prerendering (PPR): Next.js pre-renderiza en build el "cascarón" estático de la página —todo lo marcado con "use cache" o sin dependencias dinámicas— y deja huecos que se rellenan en el servidor en cada request para las partes dinámicas (las que leen cookies, headers, o searchParams). El resultado es un TTFB casi instantáneo para la parte estática, con la parte personalizada llegando por streaming.

Diferencias clave

Next.js 15 (heurístico)Next.js 16 (Cache Components)
Qué se cachea por defectoDepende de la ruta completaNada, salvo que lo marques
Cómo se marcaImplícito"use cache" explícito
Invalidación selectivarevalidatePath a nivel rutacacheTag + revalidateTag granular
Predictibilidad leyendo el códigoBajaAlta

El cambio de mentalidad es el mismo que en Server Components: pasar de "el framework decide por ti" a "tú declaras la intención, el framework la respeta". Cuesta un poco de disciplina extra marcar explícitamente cada pieza cacheable, pero a cambio ganas algo que antes no tenías: poder mirar un componente y saber, sin adivinar, si se está cacheando.

Te puede interesar