Cache, ETag y límites
Las respuestas de contenido son cacheables y traen validador. Si respetas los headers, la mayoría de las visitas repetidas no transfieren cuerpo.
Headers de respuesta
Sección titulada «Headers de respuesta»HTTP/1.1 200 OKContent-Type: application/jsonCache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=60ETag: W/"…"| Directiva | Qué hace |
|---|---|
max-age=0 | El navegador siempre revalida. Nunca sirve una copia local sin preguntar. |
s-maxage=60 | Las cachés compartidas (CDN) pueden servir la respuesta hasta 60 segundos sin consultar al origen. |
stale-while-revalidate=60 | Pasados esos 60 segundos, la CDN puede seguir sirviendo la copia vieja hasta 60 segundos más mientras refresca por detrás. |
La consecuencia práctica: un cambio del comerciante puede tardar hasta unos dos minutos en verse en todos lados. No es un bug; es el margen de la caché de borde.
Del lado del origen hay una segunda caché, por tienda y por tipo de sección
(content:{store}:{modulo}, con módulos como image-carousel o spec-carousel). Cada
edición del comerciante —contenido, visibilidad, orden, archivado o estilo— invalida
únicamente las entradas de su tienda, así que el contenido nuevo entra en la respuesta
en cuanto la caché de borde revalida. No hay nada que purgar desde el tema.
Revalidar con ETag
Sección titulada «Revalidar con ETag»El ETag es un validador opaco. Guárdalo y devuélvelo en la siguiente petición:
GET /api/public/content/{token}/product/333333174If-None-Match: W/"…"Si nada cambió, la API responde:
HTTP/1.1 304 Not ModifiedCache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=60ETag: W/"…"Sin cuerpo. Ahorras toda la transferencia del JSON.
En el navegador: no lo manejes manualmente
Sección titulada «En el navegador: no lo manejes manualmente»Desde un tema, deja que el navegador se encargue. Su caché HTTP envía el
If-None-Match por su cuenta y te entrega el cuerpo cacheado cuando llega un
304. Desde tu código eso se ve como un 200 normal, sin que tengas que
guardar nada.
Es una razón para no desactivar la caché con cache: 'no-store': pierdes la
revalidación gratuita.
En un servidor o un script
Sección titulada «En un servidor o un script»Sin CORS de por medio, ahí sí administras el ETag tú mismo:
let etag = null;let cacheado = null;
async function traerConEtag(url) { const res = await fetch(url, { headers: etag ? { 'If-None-Match': etag } : {}, });
if (res.status === 304) return cacheado;
etag = res.headers.get('ETag'); cacheado = await res.json(); return cacheado;}Límite de peticiones
Sección titulada «Límite de peticiones»600 peticiones por minuto, por tienda. El límite es agregado: lo comparten todos los visitantes de esa tienda, no es por IP ni por sesión.
Al superarlo, la API responde 429.
En uso normal desde un tema no se alcanza: una visita hace una o dos llamadas, y la caché de borde absorbe el grueso del tráfico repetido. Si lo estás viendo, casi siempre es una llamada por sección en vez de una por página.
Cachear del lado del tema
Sección titulada «Cachear del lado del tema»La caché HTTP resuelve las visitas repetidas. Lo que no resuelve son las llamadas duplicadas dentro de una misma carga: tres secciones del tema pidiendo el mismo bundle al mismo tiempo son tres requests, porque ninguna terminó todavía cuando empiezan las otras.
Eso se arregla compartiendo la promesa entre secciones, que es lo que hace
traerBundle en
el módulo cliente.
