Qué es un Service Worker: ciclo de vida, caché y límites

Un service worker es un script entre la página web y la red. Ciclo de vida, patrones de caché, límites y errores comunes explicados.

¿Qué es un service worker?

Un service worker es un archivo JavaScript que el navegador ejecuta en segundo plano, separado de la página, y que puede interceptar las peticiones de red de las páginas de su ámbito. MDN lo describe como un servidor proxy situado entre la aplicación web, el navegador y la red. Como puede responder peticiones desde una caché, hace posible el uso sin conexión y las cargas repetidas casi instantáneas. Es la base de las aplicaciones web progresivas.

Cómo funciona

La página registra el worker con navigator.serviceWorker.register('/sw.js'). Después pasa por un ciclo de vida:

  1. Install. Se dispara cuando el navegador encuentra un archivo de worker nuevo. Aquí el worker suele crear una caché y guardar los recursos que la aplicación necesita sin conexión.
  2. Waiting. Si un worker anterior sigue controlando páginas abiertas, el nuevo espera. Solo se activa cuando ninguna página usa la versión antigua, salvo que llame a skipWaiting().
  3. Activate. Buen momento para borrar cachés antiguas. Un worker recién instalado no controla las páginas ya abiertas hasta que se recargan, salvo que llame a clients.claim().
  4. Fetch y otros eventos. El worker gestiona los eventos fetch y decide qué devolver con respondWith(). También puede recibir mensajes push y eventos de sincronización en segundo plano.
  5. Update. El navegador vuelve a descargar el archivo del worker al navegar a una página del ámbito, y también cuando salta un evento y el archivo no se ha comprobado en las últimas 24 horas. Si el archivo cambió, se instala como una versión nueva.

Dos restricciones importan en la práctica. Un service worker solo funciona en un contexto seguro, es decir, con HTTPS (localhost cuenta como seguro para desarrollar). Y se ejecuta en un contexto de worker: sin acceso al DOM, sin XHR síncrono y sin Web Storage. Las páginas se comunican con él mediante postMessage(). El navegador puede detener un worker inactivo, por eso el trabajo que debe terminar se envuelve en event.waitUntil().

Patrones de caché habituales

  • Caché primero, red como respaldo. Devuelve la copia guardada si existe y, si no, la descarga. Va bien para CSS, JS y fuentes con huella en el nombre.
  • Red primero, caché como respaldo. Prueba la red y sirve la caché si no hay conexión. Va bien para HTML que debe estar al día.
  • Stale while revalidate. Responde ya desde la caché y actualiza la caché en segundo plano. Va bien para contenido que puede estar algo desfasado.
  • Página sin conexión. Si la petición no está en caché y la red falla, devuelve una página offline preparada en lugar de un error.
  • Navigation preload. Lanza la petición de red en paralelo al arranque del worker para que este no añada latencia a las navegaciones.

Ejemplo

Un sitio de noticias precachea su app shell (esqueleto HTML, CSS, JS) en el evento install. En cada petición, el worker sirve los recursos estáticos con caché primero y las páginas de artículos con red primero, recurriendo a la última copia guardada sin conexión. Cuando el equipo publica un sw.js nuevo con la caché v2, el manejador de activate borra la caché v1.

Errores comunes

  • Servir el HTML con caché primero y sin salida. Los usuarios siguen viendo la página antigua hasta que el worker se actualiza. Usa red primero para los documentos y versiona tus cachés.
  • Olvidar waitUntil(). El worker puede detenerse antes de terminar de escribir en la caché.
  • No clonar las respuestas. El cuerpo de una respuesta solo se puede leer una vez, así que hay que clonarla antes de guardarla y devolverla.
  • Usar skipWaiting() sin pensarlo. Un worker nuevo puede tomar el control de una página cargada con los recursos antiguos.
  • Cachear sin cuidado respuestas de API o páginas autenticadas. La caché de un worker no sigue por sí sola las reglas de frescura de HTTP; la caducidad la defines tú. La parte de cabeceras está en caché de API.
  • Ignorar la primera visita. Registrar e instalar el worker cuesta ancho de banda y CPU antes de que exista ningún beneficio en visitas repetidas.

Service workers, capas de caché y rendimiento

Un service worker es una capa entre varias. La caché HTTP del navegador sigue las cabeceras Cache-Control, una CDN sirve copias compartidas desde el borde, y el almacenamiento de la Cache API del worker lo controla tu propio código. Un web worker es otra cosa: saca el cómputo del hilo principal, pero no intercepta peticiones. En una aplicación de una sola página, un worker que cachea el app shell puede acelerar las cargas repetidas. El efecto solo se refleja en las Core Web Vitals cuando las páginas se sirven desde la caché, así que mídelo en lugar de suponerlo: compara las visitas repetidas con monitorización de usuarios reales y sigue las puntuaciones de laboratorio con auditorías de Lighthouse programadas. Las cachés también cambian lo que mide una prueba de rendimiento, como explican nuestras guías sobre pruebas de carga de aplicaciones web progresivas y la invalidación de caché en las pruebas de rendimiento. Para la API completa, consulta la referencia de la Service Worker API en MDN.

Preguntas frecuentes: Service Workers

¿Necesito un service worker?

Solo si quieres soporte sin conexión, notificaciones push o control programático de la caché. Un sitio que ya carga rápido y tiene pocos visitantes recurrentes puede ganar poco a cambio de la complejidad añadida.

¿Qué diferencia hay entre un service worker y un web worker?

Un web worker ejecuta scripts en un hilo secundario para que el cálculo pesado no bloquee la página. Un service worker se sitúa entre la página y la red, puede responder peticiones desde una caché y sigue activo más allá de una sola visita a la página.

¿Por qué mi service worker nuevo no surte efecto?

La versión nueva se instala pero espera hasta que ninguna página abierta use la anterior. Cierra todas las pestañas o llama a skipWaiting() y clients.claim() si aceptas las contrapartidas.

¿Un service worker necesita HTTPS?

Sí. Los service workers solo están disponibles en contextos seguros. Los navegadores también tratan http://localhost como seguro para que puedas desarrollar en local.

¿Puede un service worker ver o modificar el DOM de la página?

No. No tiene acceso al DOM y se ejecuta en otro hilo. Intercambia mensajes con las páginas mediante postMessage().

¿Cómo me deshago de un service worker defectuoso?

Publica un sw.js de reemplazo que vacíe sus cachés en el evento activate, o anula su registro desde la página. Prepara este interruptor de emergencia antes de publicar, porque un worker que cachea HTML puede seguir sirviendo páginas obsoletas.

¿Qué tan rápido es tu sitio web?

Mejora su velocidad y SEO sin problemas con nuestra Prueba de Velocidad gratuita.

Prueba de velocidad de sitio web gratis

Analice la velocidad de carga de su sitio web y mejore su rendimiento con nuestro comprobador de velocidad de página gratuito.