Service worker para obtener modo sin conexión
Introducción
Los service workers actúan como proxies en segundo plano. Cuando se realiza una petición de red a través de nuestro sitio web, primero pasan por el service worker que está en uso. Gracias a esto y a otros APIs como el de almacenamiento en caché, podemos interceptar una petición de red y devolver inmediatamente una versión cacheada, obteniendo disponibilidad frente a fallos de red (modo offline), a la vez que velocidad al no tener que llevar la petición hasta el servidor.
El problema de esta estrategia conocida como offline-first es que siempre se muestra la versión guardada aunque no sea la más actual. Este problema se puede solventar de muchas maneras como por ejemplo:
-
Mostrar la versión guardada y realizar en segundo plano una nueva petición de red para guardarla en caché. Tras esto se le informa al usuario de que hay nuevos datos para que refresque la página y vea la nueva versión.
-
Mediante técnicas de invalidación de caché para eliminar la versión guardada de las páginas que están obsoletas.
-
Creando una caché nueva en cada despliegue. A esto se le conoce como versionamiento:
cache-v1
,cache-v2
, etc. Cada nuevo despligue invalida y elimina las cachés antiguas.
Estas soluciones añaden bastante complejidad, sobre todo si se realizan desde cero sin utilizar alguna librería como Workbox.
Por estos motivos he cambiado la estrategia de este blog de offline-first a network-first con modo sin conexión. No es perfecto pero es una manera bastante simple de ofrecer modo offline a páginas ya visitadas, a la vez que evitar lidiar con páginas que se quedan obsoletas.
Aquí aparece una curiosidad que admito me costó un rato solucionar. ¿Sabrías decir por qué esto no funciona?
Las funciones como event.waitUntil()
o event.respondWith()
no aceptan una función como argumento, si no una promesa. Por lo tanto que hay que llamar a la función asíncrona (por ejemplo, mediante un IIFE) para que devuelva una promesa y se pase como argumento.
Service worker - install
El fichero sw.js
comienza con el evento de instalación. Éste se ejecuta cuando se instala el service worker por primera vez en el navegador del usuario.
Service worker - activate
Posteriormente activamos el service worker:
Service worker - fetch
Y ya por último el evento fetch
se encarga de interceptar las peticiones de red y gestionar toda la estrategia. Veamos paso por paso a través de los comentarios.
Si quieres acceder a la versión del service worker sin comentarios para poder copiar y pegar, recuerda que lo tienes en /sw.js o en el repositorio del blog en GitHub, dentro de snippets/service-worker-to-get-offline-mode/sw.js.
Puedes apoyarme para que pueda dedicar aún más tiempo a escribir artículos y tener recursos para crear nuevos proyectos. ¡Gracias!