Demostración práctica de cacheo granular por campo usando Cache Components en Next.js 16
Este proyecto demuestra cómo cachear campos individuales de un registro con diferentes estrategias en Next.js 16.
Tienes un producto con 3 campos que cambian a diferentes velocidades:
- Texto (nombre + descripción): Rara vez cambia
- Precio: Cambia ocasionalmente
- Stock: Debe estar siempre actualizado
¿Cómo cacheas cada campo independientemente?
Cada campo es un componente async separado con su propia query y estrategia de cache.
// ✅ Cada campo con su estrategia
<ProductText productId={id} /> // Cacheado 1 semana
<ProductPrice productId={id} /> // Cacheado 1 hora
<Suspense>
<ProductStock productId={id} /> // Sin cache (streaming)
</Suspense>- ✅ Cacheo granular por campo - Control independiente de cada dato
- ✅ Queries separadas - Una query por campo, optimización automática
- ✅ Tags para revalidación - Invalida solo lo que cambió
- ✅ Static shell + Streaming - HTML instantáneo + datos frescos
- ✅ Suspense correcto - Ejemplos de dónde va y por qué
- ✅ Demo interactiva - Botones para probar revalidación en vivo
- ✅ Rutas estáticas de producto -
generateStaticParamspara reforzar PPR educativo - ✅ Validación con Zod - Sanitización de
productIden Server Actions - ✅ Tailwind + shadcn/ui - UI moderna y profesional
- ✅ TypeScript - Type-safe en toda la app
- ✅ Mock DB con logs - Ve qué queries se ejecutan y cuándo
ProductPage (padre - sync)
│
└─ <Suspense>
└─ ProductContent (async - accede a params)
├─ ProductText (async + 'use cache' + cacheLife('weeks'))
├─ ProductPrice (async + 'use cache' + cacheLife('hours'))
└─ <Suspense>
└─ ProductStock (async sin cache - streaming)
# Instalar dependencias
bun install
# Ejecutar en desarrollo
bun dev- Home muestra lista de productos
- Click en cualquier producto
- Observa los badges de color indicando qué está cacheado
- Abre DevTools → Network
- Disable cache
- Navega a un producto
- Ve cómo el HTML inicial ya tiene texto y precio
- Ve cómo el stock llega después (streaming)
En la consola verás:
[DB Query] 📝 getProductText - Product 1
[DB Query] 💰 getProductPrice - Product 1
[DB Query] 📦 getProductStock - Product 1
- Click en "Revalidar Precio"
- Refresh la página
- Solo el precio se regenera
- El texto mantiene su cache
// El componente async ES una promesa
async function ProductStock({ productId }) {
const stock = await db.getStock(productId)
return <div>{stock}</div>
}
// Por eso Suspense va en el PADRE
<Suspense fallback="Loading...">
<ProductStock /> {/* ← Esta línea crea la promesa */}
</Suspense>Sí, son múltiples queries, pero:
- Las cacheadas se ejecutan en build time → static shell
- Las dinámicas se ejecutan en request time → streaming
- Total: Mejor performance percibida
// Cachear con tag
cacheTag(`product-price-${productId}`)
// Revalidar solo ese campo
revalidateTag(`product-price-${productId}`, 'max')/docs- Introducción/docs/implementation- Implementación completa/docs/concepts- Conceptos clave/docs/revalidation-updateTagvsrevalidateTag/docs/benefits- Beneficios
- Documentación oficial de Cache Components
- use cache directive
- cacheLife API
- cacheTag API
- revalidateTag API
- Next Skills
Causa: Componente async sin cache ni Suspense
Solución: Agregar <Suspense> en el padre o 'use cache' en el componente
Causa: Browser cache activado
Solución: Hard refresh (Ctrl+Shift+R) o ventana privada
Causa: Tag incorrecto
Solución: Verificar que el tag sea idéntico en cache y revalidación, por ejemplo:
cacheTag(`product-price-${productId}`)
revalidateTag(`product-price-${productId}`, 'max')Las contribuciones son bienvenidas! Por favor:
- Fork el proyecto
- Crea una rama (
git checkout -b feature/amazing-feature) - Commit tus cambios (
git commit -m 'Add amazing feature') - Push a la rama (
git push origin feature/amazing-feature) - Abre un Pull Request
MIT
Creado para demostrar Cache Components en Next.js 16
⭐ Si este proyecto te ayudó a entender Cache Components, dale una estrella!
Este proyecto demuestra patrones avanzados de Next.js 16:
- Cacheo granular con
use cache - Suspense boundaries correctos
- Runtime data handling
- Revalidación selectiva con tags
- Static shell + Streaming (PPR)
Úsalo como referencia para tus proyectos reales.