Cómo trabajar con service workers

En este codelab, se muestra cómo registrar un service worker desde tu aplicación web y usar las Herramientas para desarrolladores de Chrome para observar su comportamiento. También abarca algunas técnicas de depuración que pueden resultarte útiles cuando trabajes con service workers.

Familiarízate con el proyecto de ejemplo

Los archivos del proyecto de ejemplo más relevantes para este codelab son los siguientes:

  • register-sw.js comienza vacío, pero contendrá el código que se usa para registrar el service worker. Ya se está cargando a través de una etiqueta <script> dentro del index.html del proyecto.
  • service-worker.js está igualmente vacío. Es el archivo que contendrá el trabajador de servicio para este proyecto.

Agrega el código de registro del service worker

No se usará un trabajador de servicio (ni siquiera uno vacío, como el archivo service-worker.js actual) a menos que se registre primero. Puedes hacerlo con una llamada a:

navigator.serviceWorker.register(
  '/service-worker.js'
)

dentro de tu archivo register-sw.js.

Sin embargo, antes de agregar ese código, debes tener en cuenta algunos puntos.

En primer lugar, no todos los navegadores admiten service workers. Esto es especialmente cierto en el caso de las versiones anteriores de los navegadores que no se actualizan automáticamente. Por lo tanto, se recomienda llamar a navigator.serviceWorker.register() de forma condicional, después de verificar si se admite navigator.serviceWorker.

En segundo lugar, cuando registras un trabajador de servicio, el navegador ejecuta el código en tu archivo service-worker.js y, potencialmente, puede comenzar a descargar URLs para completar las memorias caché, según el código de los controladores de eventos install y activate de tu trabajador de servicio.

La ejecución de código adicional y la descarga de recursos pueden consumir recursos valiosos que tu navegador podría usar para mostrar la página web actual. Para evitar esta interferencia, es una buena práctica retrasar el registro de un service worker hasta que el navegador termine de renderizar la página actual. Una forma conveniente de aproximar esto es esperar hasta que se haya activado el evento window.load.

Si juntas esos dos puntos, agrega este código de registro de Service Worker de uso general a tu archivo register-sw.js:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js');
  });
}

Agrega código de registro del service worker

En el archivo service-worker.js, se incluye toda la lógica para la implementación de tu trabajador de servicio. Usarías una combinación de los eventos de ciclo de vida del trabajador de servicio, la API de Cache Storage y el conocimiento sobre el tráfico de red de tu app web para crear un trabajador de servicio perfectamente diseñado y listo para controlar todas las solicitudes de tu app web.

Pero… eso lo aprenderás más adelante. En esta etapa, el objetivo es observar varios eventos del service worker y familiarizarse con el uso de las Herramientas para desarrolladores de Chrome para depurar el estado del service worker.

Para ello, agrega el siguiente código a service-worker.js, que registrará mensajes en la consola de Herramientas para desarrolladores en respuesta a varios eventos (pero no hará mucho más):

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

self.addEventListener('activate', (event) => {
  console.log('Inside the activate handler:', event);
});

self.addEventListener(fetch, (event) => {
  console.log('Inside the fetch handler:', event);
});

Familiarízate con el panel Service Workers en Herramientas para desarrolladores

Ahora que agregaste el código a los archivos register-sw.js y service-worker.js, es momento de visitar la versión en vivo de tu proyecto de muestra y observar el service worker en acción.

  • Para obtener una vista previa del sitio, presiona Ver app y, luego, Pantalla completa pantalla completa.
  • Presiona "Control + Mayúsculas + J" (o "Comando + Opción + J" en Mac) para abrir DevTools.
  • Haz clic en la pestaña Consola.

Deberías ver mensajes de registro similares a los siguientes, que muestran que el service worker se instaló y activó:

Muestra que el service worker está instalado y activado.

Luego, ve a la pestaña Applications y selecciona el panel Service Workers. Deberías ver un resultado similar al siguiente:

Muestra los detalles del service worker en el panel de service worker.

Esto te indica que hay un trabajador de servicio con una URL de origen de service-worker.js, para la app web solar-donkey.glitch.me, que está activado y en ejecución. También te indica que, actualmente, hay un cliente (pestaña abierta) que controla el service worker.

Puedes usar los vínculos de este panel, como Unregister o stop, para realizar cambios en el service worker registrado actualmente con fines de depuración.

Cómo activar el flujo de actualización del trabajador de servicio

Uno de los conceptos clave que debes comprender cuando desarrollas con Service Workers es la idea de un flujo de actualización.

Después de que los usuarios visiten una app web que registra un service worker, terminarán con el código de la copia actual de service-worker.js instalada en su navegador local. Pero ¿qué sucede cuando actualizas la versión de service-worker.js que se almacena en tu servidor web?

Cuando un visitante recurrente regresa a una URL que se encuentra dentro del alcance de un Service Worker, el navegador solicitará automáticamente el service-worker.js más reciente y verificará si hay cambios. Si algo en la secuencia de comandos del service worker es diferente, el nuevo service worker tendrá la oportunidad de instalarse, activarse y, finalmente, tomar el control.

Para simular este flujo de actualización, vuelve al editor de código de tu proyecto y realiza cualquier cambio en el código. Un cambio rápido sería reemplazar

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

con

self.addEventListener('install', (event) => {
  console.log('Inside the UPDATED install handler:', event);
});

Después de realizar ese cambio, vuelve a la versión en vivo de tu app de ejemplo y vuelve a cargar la página con la pestaña Aplicación de Herramientas para desarrolladores aún abierta. Deberías ver un resultado similar al siguiente:

Muestra dos versiones del service worker instalado.

Esto muestra que hay dos versiones de tu service worker instaladas en este punto. La versión anterior, que ya estaba activada, se está ejecutando y controla la página actual. La versión actualizada del service worker se muestra a continuación. Se encuentra en el estado waiting y permanecerá en espera hasta que se cierren todas las pestañas abiertas que controla el service worker anterior.

Este comportamiento predeterminado garantiza que, si tu nuevo service worker tiene una diferencia fundamental en el comportamiento con respecto al anterior (como un controlador fetch que responde con recursos que son incompatibles con versiones anteriores de tu app web), no entrará en vigencia hasta que un usuario haya cerrado todas las instancias anteriores de tu app web.

En resumen

Ahora deberías sentirte cómodo con el proceso de registro de un service worker y la observación de su comportamiento con las Herramientas para desarrolladores de Chrome.

Ahora estás en una buena posición para comenzar a implementar estrategias de almacenamiento en caché y todo lo que te ayudará a que tu app web se cargue de forma confiable y rápida.