Cómo trabajar con service workers

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

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 usó para registrar el trabajador de servicio. Ya se carga a través de una etiqueta <script> dentro del index.html del proyecto.
  • service-worker.js también está vacío. Es el archivo que contendrá el trabajador de servicio de este proyecto.

Agrega el código de registro del service worker

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

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

dentro del archivo register-sw.js.

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

En primer lugar, no todos los navegadores admiten los service workers. Esto es especialmente cierto para las versiones anteriores de 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 navigator.serviceWorker es compatible.

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

Ejecutar código adicional y descargar recursos puede agotar recursos valiosos que tu navegador podría usar para mostrar la página web actual. Para evitar esta interferencia, se recomienda retrasar el registro de un service worker hasta que el navegador termine de renderizar la página actual. Una forma conveniente de aproximarse a esto es esperar hasta que se active el evento window.load.

Combinando esos dos puntos, agrega este código de registro del trabajador de servicio 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

Tu archivo service-worker.js es donde normalmente iría toda la lógica para la implementación del trabajador de servicio. Usarías una combinación de los eventos del 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, listo para controlar todas las solicitudes de tu app web.

Pero… eso es todo por ahora. En esta etapa, el enfoque se centra en observar varios eventos del servicio de trabajo y acostumbrarse a usar DevTools de Chrome para depurar el estado de tu servicio de trabajo.

Para ello, agrega el siguiente código a service-worker.js, que registrará mensajes en la consola de DevTools 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 DevTools

Ahora que agregaste el código a los archivos register-sw.js y service-worker.js, es hora de visitar la versión publicada de tu proyecto de ejemplo y observar el trabajador de servicio en acción.

  • Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona 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 un mensaje de registro similar al siguiente, que muestra que se instaló y activó el trabajador de servicio:

Muestra que el service worker está instalado y activado.

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

Muestra los detalles del trabajador de servicio en el panel del trabajador de servicio.

Esto te permite saber que hay un service worker 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 trabajador de servicio registrado actualmente con fines de depuración.

Activa el flujo de actualización del trabajador de servicio

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

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

Cuando un visitante recurrente regresa a una URL que está dentro del alcance de un trabajador de servicio, el navegador solicitará automáticamente el service-worker.js más reciente y comprobará 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 hacer ese cambio, vuelve a la versión publicada de tu app de ejemplo y vuelve a cargar la página con la pestaña Application de DevTools abierta. Deberías ver algo similar a lo siguiente:

Muestra dos versiones del trabajador de servicio instaladas.

Esto muestra que hay dos versiones de tu trabajador de servicio 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 trabajador de servicio aparece a continuación. Está 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 trabajador de servicio tiene una diferencia fundamental en el comportamiento con el anterior (como un controlador fetch que responde con recursos incompatibles con versiones anteriores de tu app web), no entrará en vigencia hasta que un usuario cierre todas las instancias anteriores de tu app web.

En resumen

Ahora deberías estar familiarizado con el proceso de registrar un service worker y observar su comportamiento con las herramientas de Chrome DevTools.

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