Update

Publicaste tu AWP: algunos usuarios la usan desde el navegador, otros la instalan en sus dispositivos. Cuando actualizas la app, es importante que apliques las prácticas recomendadas para evitar errores.

Puedes actualizar lo siguiente:

  • Datos de apps.
  • Los recursos ya están almacenados en caché en los dispositivos.
  • El archivo del service worker o sus dependencias
  • Metadatos del manifiesto

Veamos las prácticas recomendadas para cada uno de estos elementos.

Cómo actualizar datos

Para actualizar datos, como los almacenados en IndexedDB, puedes usar herramientas como Fetch, WebRTC o la API de WebSockets. Si tu app admite funciones sin conexión, recuerda mantener también actualizados los datos que admiten las funciones.

En los navegadores compatibles, existen opciones para sincronizar datos, no solo cuando el usuario abre la AWP, sino también en segundo plano. Estas opciones son las siguientes:

  • Sincronización en segundo plano: Guarda las solicitudes que fallaron y vuelve a intentarlas mediante la sincronización del service worker.
  • Sincronización periódica en segundo plano de la Web: Sincroniza datos periódicamente en segundo plano y en momentos específicos, lo que permite que la app proporcione datos actualizados, incluso si el usuario aún no la abrió.
  • Recuperación en segundo plano: Descarga archivos grandes, incluso cuando la AWP está cerrada.
  • push web: envía un mensaje desde el servidor que activa el service worker y notifica al usuario. Por lo general, esto se denomina “notificación push”. Esta API requiere el permiso del usuario.

Todas estas APIs se ejecutan desde el contexto del service worker. Actualmente, solo están disponibles en los navegadores basados en Chromium, en Android y en los sistemas operativos de escritorio. Cuando usas una de estas API, puedes ejecutar código en el subproceso del service worker; por ejemplo, para descargar datos de tu servidor y actualizar tus datos de IndexedDB.

Actualizando elementos

La actualización de elementos incluye cualquier cambio en los archivos que utilizas para renderizar la interfaz de la app, como HTML, CSS, imágenes y JavaScript. Por ejemplo, un cambio en la lógica de tu app, una imagen que forma parte de tu interfaz o una hoja de estilo CSS.

Actualizar patrones

Estos son algunos patrones comunes para manejar las actualizaciones de las apps, pero puedes personalizar el proceso según tus necesidades:

  • Actualización completa: cada cambio, incluso uno menor, activa el reemplazo de todo el contenido de la caché. Este patrón imita la manera en que las apps específicas de dispositivos manejan las actualizaciones, consumirá más ancho de banda y llevará más tiempo.
  • Actualización de los recursos modificados: Solo los recursos que cambiaron desde la última actualización se reemplazan en la caché. A menudo, se implementa con una biblioteca como Workbox. Implica crear una lista de archivos almacenados en caché, una representación de hash del archivo y marcas de tiempo. Con esta información, el service worker compara esta lista con los elementos almacenados en caché y decide qué elementos actualizar.
  • Actualización de activos individuales: Cada recurso se actualiza de manera individual cuando cambia. La estrategia de inactividad durante la revalidación que se describe en el capítulo Publicación es un ejemplo de actualización de activos de forma individual.

Cuándo actualizar

Otra práctica recomendada es encontrar un buen momento para verificar si hay actualizaciones y aplicarlas. Aquí tienes algunas opciones:

  • Cuando se activa el service worker No hay eventos para escuchar en este momento, pero el navegador ejecutará cualquier código en el alcance global del service worker cuando se active.
  • En el contexto de la ventana principal de tu AWP, después de que el navegador cargó la página, para evitar que la app se cargue más lento.
  • Cuando se activan eventos en segundo plano, como cuando tu AWP recibe una notificación push o se activa una sincronización en segundo plano. Luego, puedes actualizar tu caché para que los usuarios tengan la nueva versión del recurso la próxima vez que abran la app.

Actualizaciones en tiempo real

También puedes elegir si quieres aplicar una actualización cuando la app esté abierta (en vivo) o cerrada. Con el enfoque de cierre de la app, aunque la app haya descargado recursos nuevos, no realizará ningún cambio y usará las versiones nuevas en la próxima carga.

Una actualización en tiempo real significa que, apenas se actualiza el recurso en la caché, tu AWP reemplaza el recurso en la carga actual. Es una tarea compleja que no se aborda en este curso. Algunas herramientas que ayudan a implementar esta actualización son livereload-js y la API de CSSStyleSheet.replace() de actualización de los recursos de CSS.

Actualiza el service worker

El navegador activa un algoritmo de actualización cuando cambian tu service worker o sus dependencias. El navegador detecta actualizaciones mediante una comparación byte por byte entre los archivos almacenados en caché y los recursos que provienen de la red.

A continuación, el navegador intenta instalar la nueva versión del service worker, y el nuevo service worker se encuentra en el estado Waiting, como se describe en el capítulo Service Workers. La instalación nueva ejecutará el evento install para el service worker nuevo. Si almacenas recursos en caché en ese controlador de eventos, los recursos también se volverán a almacenar en caché.

Detecta cambios en el service worker

Para detectar que un nuevo service worker está listo y instalado, usamos el evento updatefound del registro del service worker. Este evento se activa cuando el service worker nuevo comienza a instalarse. Debemos esperar a que su estado cambie a installed con el evento statechange. Consulta lo siguiente:

async function detectSWUpdate() {
  const registration = await navigator.serviceWorker.ready;

  registration.addEventListener("updatefound", event => {
    const newSW = registration.installing;
    newSW.addEventListener("statechange", event => {
      if (newSW.state == "installed") {
         // New service worker is installed, but waiting activation
      }
    });
  })
}

Forzar anulación

Se instalará el nuevo service worker, pero se espera la activación de forma predeterminada. La espera evita que el nuevo service worker se apropie de los clientes antiguos que podrían no ser compatibles con la nueva versión.

Aunque no se recomienda, el nuevo service worker puede omitir ese período de espera y comenzar la activación de inmediato.

self.addEventListener("install", event => {
   // forces a service worker to activate immediately
   self.skipWaiting();
  });

self.addEventListener("activate", event => {
  // when this SW becomes activated, we claim all the opened clients
  // they can be standalone PWA windows or browser tabs
  event.waitUntil(clients.claim());
});

El evento controllerchange se activa cuando cambia el service worker que controla la página actual. Por ejemplo, un trabajador nuevo omitió la espera y se convierte en el nuevo trabajador activo.

navigator.serviceWorker.addEventListener("controllerchange", event => {
   // The service worker controller has changed
 });

Actualiza los metadatos

También puedes actualizar los metadatos de la app, que se configuran principalmente en el manifiesto de la aplicación web. Por ejemplo, puedes actualizar el ícono, el nombre o la URL de inicio, o bien agregar una función nueva, como los accesos directos a aplicaciones. Pero ¿qué sucede con todos los usuarios que ya instalaron la app con el ícono anterior en sus dispositivos? ¿Cómo y cuándo obtienen la versión actualizada?

La respuesta depende de la plataforma. Veamos las opciones disponibles.

Safari en navegadores iOS, iPadOS y Android

En estas plataformas, la única forma de obtener los nuevos metadatos del manifiesto es reinstalar la app desde el navegador.

Google Chrome en Android con WebAPK

Cuando el usuario instale tu AWP en Android con Google Chrome con WebAPK activado (la mayoría de las instalaciones de AWP de Chrome), la actualización se detectará y aplicará en función de un algoritmo. Consulta los detalles en este artículo sobre actualizaciones del manifiesto.

Notas adicionales sobre el proceso:

Si el usuario no abre tu AWP, no se actualizará su WebAPK. Si el servidor no responde con el archivo de manifiesto (se produce un error 404), Chrome no verificará si hay actualizaciones durante 30 días como mínimo, incluso si el usuario abre la AWP.

Ve a about:webapks en Chrome para Android para ver el estado de la marca "needing update" y solicitar una actualización. En el capítulo Herramientas y depuración, encontrarás más información sobre esta herramienta de depuración.

Samsung Internet en Android con WebAPK

El proceso es similar al de la versión de Chrome. En este caso, si el manifiesto de la AWP requiere una actualización, durante las siguientes 24 horas, se actualizará el WebAPK en Wi-Fi después de crear el WebAPK actualizado.

Google Chrome y Microsoft Edge en computadoras de escritorio

En los dispositivos de escritorio, cuando se inicia la AWP, el navegador determina la última vez que verificó el manifiesto local en busca de cambios. Si el manifiesto no se revisó desde que se inició el navegador por última vez o no se revisó en las últimas 24 horas, el navegador realizará una solicitud de red para el manifiesto y, luego, lo comparará con la copia local.

Cuando se actualicen las propiedades seleccionadas, se activará una actualización después de que se cierren todas las ventanas.

Alertar al usuario

Algunas estrategias de actualización necesitan una nueva carga o una nueva navegación de los clientes. Querrás informarle al usuario que hay una actualización en espera, pero darle la oportunidad de actualizar la página cuando le resulte más conveniente.

Para ello, existen estas opciones:

  • Usa el DOM o la API de Canvas para renderizar una notificación en la pantalla.
  • Usa la API de notificaciones web. Esta API forma parte del permiso push para generar una notificación en el sistema operativo. Deberás solicitar permiso de envío web para usarla, incluso si no usas el protocolo de mensajería push de tu servidor. Esta es la única opción que tenemos si la AWP no está abierta.
  • Usa la API de Badging para mostrar que las actualizaciones están disponibles en el ícono instalada de la AWP.

Notificación de actualización que se muestra en el DOM..

Más información sobre la API de Badging

La API de insignias te permite marcar el ícono de tu AWP con un número de insignia o un punto de insignia en navegadores compatibles. Un punto de insignia es una pequeña marca dentro del ícono de instalación que indica que algo está esperando dentro de la app.

Ejemplo de Twitter con ocho notificaciones y otra app que muestra una insignia de tipo de marca.

Debes llamar a setAppBadge(count) en el objeto navigator para establecer un número de insignia. Puedes hacerlo desde el contexto de la ventana o el service worker cuando sepas que hay una actualización para alertar al usuario.

let unreadCount = 125;
navigator.setAppBadge(unreadCount);

Para borrar la insignia, llama a clearAppBadge() en el mismo objeto:

navigator.clearAppBadge();

Recursos