Un service worker puede hacer más resistentes las visitas recurrentes y evitar trabajo de red repetido, pero instalarlo no mejora automáticamente las Core Web Vitals. Lo importante es decidir qué peticiones debe gestionar, cuánta actualidad necesita cada respuesta y qué ocurre cuando cambia una versión. Empieza con un conjunto limitado de recursos públicos. Amplíalo cuando las pruebas demuestren que el beneficio justifica su mantenimiento.
Distingue el worker de la caché
Un service worker es un script que responde a eventos y puede interceptar peticiones de las páginas que controla. Cache Storage almacena, por separado, pares de peticiones y respuestas. Ninguno sustituye a la caché HTTP del navegador. Una respuesta solicitada por el worker también puede utilizar esa caché HTTP, por lo que debes identificar la capa que la sirvió antes de atribuir una mejora a tu código.
Cache Storage no aplica automáticamente las reglas de frescura de HTTP. Tu aplicación decide cuándo guardar, actualizar y eliminar sus entradas. Una cabecera del servidor no sustituye esa política. Si solo buscas reutilizar hojas de estilo e imágenes públicas, revisa primero la configuración de la caché del navegador antes de introducir una capa programable.
Elige una estrategia para cada recurso
Para recursos públicos cuya URL contiene una huella de su contenido, consultar la caché antes que la red es un punto de partida razonable. Una URL que no cambia representa un contenido que tampoco cambia. Ese razonamiento no sirve para datos de una cuenta, disponibilidad o HTML que deba reflejar una nueva publicación.
Consultar primero la red favorece la actualidad, pero puede dejar al visitante esperando si la conexión falla. Define expresamente cómo se cancela la petición, qué alternativa se ofrece y cómo se comunica el error. Servir una copia guardada mientras se actualiza en segundo plano facilita la reutilización rápida, aunque el visitante actual puede ver contenido anterior. Además, genera tráfico incluso cuando ya existe una copia en caché.
Son decisiones de producto. Una página de ayuda disponible sin conexión puede resultar útil; una confirmación de pago desactualizada puede inducir a error. No apliques una estrategia universal solo porque todas las peticiones pasan por el mismo manejador.
No pierdas de vista la primera visita
Registro, instalación, activación y control son estados diferentes. Un worker recién registrado normalmente no controla la página inicial que lo registró. Las visitas posteriores pueden beneficiarse cuando esté preparado, mientras que el visitante nuevo sigue dependiendo de la carga habitual.
Guardar demasiados recursos por adelantado puede competir con los que necesita la página actual. Precarga únicamente lo necesario para una experiencia deliberada. Mejora por separado la respuesta del servidor, el descubrimiento de recursos y el renderizado. La guía para reducir el tiempo de respuesta del servidor sigue siendo pertinente aunque una visita ya almacenada parezca rápida.
Empieza con un ejemplo de alcance limitado
Este worker ilustrativo guarda por adelantado una lista explícita de recursos públicos y utiliza esa caché para las peticiones coincidentes cuando es posible. Ponlo en un archivo de worker, regístralo por separado en un contexto seguro y sustituye las rutas por archivos reales. Las respuestas incluidas deben ser públicas e independientes del estado de autenticación.
const CACHE = "editorialAssetsRelease";
const ASSETS = [
"/assets/site.abc123.css",
"/assets/brand.def456.svg"
];
self.addEventListener("install", event => {
event.waitUntil(
caches.open(CACHE).then(cache => cache.addAll(ASSETS))
);
});
self.addEventListener("fetch", event => {
const request = event.request;
const url = new URL(request.url);
if (request.method !== "GET" ||
url.origin !== self.location.origin ||
!ASSETS.includes(url.pathname + url.search)) return;
event.respondWith((async () => {
let cached;
try {
const cache = await caches.open(CACHE);
cached = await cache.match(request);
} catch {}
return cached || fetch(request);
})());
});En cada publicación, cambia conjuntamente el nombre de la caché y las URL con huella de contenido. Si falla una petición obligatoria durante la precarga, puede fallar la instalación. El ejemplo no incorpora HTML alternativo, una caché que crezca durante el uso ni toma de control automática tras una actualización. Así queda claro su alcance. La integración real todavía necesita registro, gestión de actualizaciones y retirada de las cachés pertenecientes a esta aplicación.
Diseña actualizaciones compatibles con las pestañas abiertas
Un worker recién instalado puede permanecer en espera mientras el activo atiende a los clientes existentes. Eso ayuda a evitar que una página antigua reciba recursos nuevos incompatibles. skipWaiting() y clients.claim() modifican el ciclo de vida y el control de las páginas; no son optimizaciones de velocidad que deban añadirse por defecto.
Decide si conviene mostrar un aviso de actualización, esperar una recarga natural o mantener versiones compatibles en paralelo. Conserva los recursos anteriores con huella de contenido mientras las páginas existentes puedan solicitarlos. Elimina solo las cachés que pertenezcan a tu aplicación y aplica una política de conservación que tenga en cuenta a los clientes activos. Consulta la documentación del ciclo de vida de los service workers al diseñar esa transición.
Protege el contenido privado y contempla la pérdida de almacenamiento
Evita almacenar autenticación, páginas de cuenta y respuestas de API sensibles salvo que un diseño revisado específicamente lo requiera. Una lista explícita de URL permitidas es más fácil de revisar que guardar todas las peticiones satisfactorias. No supongas que una cookie o una cabecera vuelve seguro un manejador general de Cache Storage.
Si la aplicación almacena deliberadamente contenido de un usuario, diseña conjuntamente el cierre de sesión, el cambio de cuenta y la eliminación de datos. También debes contemplar que el navegador elimine recursos guardados. La experiencia sin conexión tiene que explicar qué sigue disponible y qué exige conectividad. La ausencia de datos nunca debe convertirse en una acción aparentemente completada.
Prueba estados distintos, no solo una recarga con caché
Compara una visita limpia, una visita controlada con almacenamiento poblado, una visita sin conexión y una actualización con una pestaña antigua abierta. Comprueba el ámbito del worker, qué worker controla la página, las entradas reales de Cache Storage y el origen de las respuestas. Desactivar la caché HTTP en las herramientas de desarrollo no demuestra por sí solo que se haya evitado Cache Storage.
Utiliza una traza para investigar la lentitud y mediciones de campo para comprobar la experiencia de los visitantes. Los límites de una buena experiencia son LCP igual o inferior a 2.5 s, INP igual o inferior a 200 ms y CLS igual o inferior a 0.1, evaluados en el percentil 75 y separando móvil y escritorio. Una visita local repetida que resulta rápida no demuestra que la distribución de campo cumpla esos límites.
Mantén el worker cuando su aportación esté clara. Contenido correcto, actualizaciones previsibles y recuperación fiable forman parte de la ingeniería de rendimiento. La guía sobre datos de campo y laboratorio ayuda a interpretar cada observación en su contexto.