Apps web progresivas: Cómo trabajar con Workbox

1. Te damos la bienvenida

En este lab, tomarás un sitio web con un service worker existente y lo convertirás para que use Workbox. Este es el segundo de una serie de codelabs complementarios para el taller de apps web progresivas. El codelab anterior fue Going Offline. Hay seis codelabs más en esta serie.

Qué aprenderás

  • Cómo convertir un Service Worker existente para usar Workbox
  • Agrega un resguardo sin conexión a una PWA

Lo que debe saber

  • Conocimientos básicos de HTML y JavaScript

Lo que necesitarás

2. Prepárate

Para comenzar, clona o descarga el código de partida necesario para completar este codelab:

Si clonas el repositorio, asegúrate de estar en la rama pwa03--workbox. El archivo ZIP también contiene el código de esa rama.

Este código base requiere Node.js 14 o una versión posterior. Una vez que tengas el código disponible, ejecuta npm ci desde la línea de comandos en la carpeta del código para instalar todas las dependencias que necesitarás. Luego, ejecuta npm start para iniciar el servidor de desarrollo del codelab.

El archivo README.md del código fuente proporciona una explicación de todos los archivos distribuidos. Además, los siguientes son los archivos existentes clave con los que trabajarás a lo largo de este codelab:

Archivos de claves

  • service-worker.js: Archivo del service worker de la aplicación
  • offline.html: HTML sin conexión para usar cuando una página no está disponible

3. Migra a Workbox

Si observamos el service worker existente, el almacenamiento previo en caché parece que se puede dividir en dos pasos:

  • Almacena en caché los archivos relevantes durante la instalación del Service Worker
  • Vuelve a entregar esos archivos con una estrategia de solo caché

El archivo index.html y la ruta / siguen teniendo sentido para el almacenamiento previo en caché, ya que el HTML de esta app web no cambiará mucho, pero los otros archivos, como CSS y JavaScript, pueden cambiar, y no queremos tener que pasar por todo el ciclo de vida del Service Worker cada vez que lo hagan. Además, el Service Worker actual solo tiene en cuenta un subconjunto de nuestro CSS y JavaScript, y queremos que se cubra todo. Almacenar en caché estos elementos con una estrategia de Stale While Revalidate tiene más sentido, ya que se obtiene una respuesta rápida que se puede actualizar en segundo plano según sea necesario.

Revisión del almacenamiento previo en caché

Cuando migramos a Workbox, no necesitamos conservar ningún código existente, por lo que borraremos todo lo que se encuentre en service-worker.js. En el lab anterior, configuramos este Service Worker para que se compile, de modo que podamos usar las importaciones de ESModule aquí para incorporar Workbox desde sus módulos de NPM. Comencemos por repasar el almacenamiento previo en caché. En service-worker.js, agrega el siguiente código:

import { warmStrategyCache } from 'workbox-recipes';
import { CacheFirst } from 'workbox-strategies';
import { registerRoute } from 'workbox-routing';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { ExpirationPlugin } from 'workbox-expiration';

// Set up page cache
const pageCache = new CacheFirst({
  cacheName: 'page-cache',
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200],
    }),
    new ExpirationPlugin({
      maxAgeSeconds: 30 * 24 * 60 * 60,
    }),
  ],
});

warmStrategyCache({
  urls: ['/index.html', '/'],
  strategy: pageCache,
});

registerRoute(({ request }) => request.mode === 'navigate', pageCache);

Explicación

Para configurar el almacenamiento previo en caché para /index.html y /, hay cinco módulos de los que puedes extraer información. Si bien puede parecer mucho, este código es mucho más potente que el código anterior escrito.

Comienza configurando una nueva estrategia de almacenamiento en caché Cache First, que se elige en lugar de una estrategia Cache Only para permitir que se agreguen otras páginas a la caché según sea necesario. Se le asigna un nombre, page-cache. Las estrategias de Workbox pueden tomar varios complementos que pueden afectar el ciclo de vida del almacenamiento y la recuperación de contenido de la caché. Aquí, se usan dos complementos, el complemento Cacheable Response y el complemento Expiration, para garantizar que solo se almacenen en caché las respuestas correctas del servidor y que cada elemento de la caché se borre después de 30 días.

A continuación, la caché de la estrategia se calienta con /index.html y / usando la receta de Workbox para calentar la caché de la estrategia. Esto agregará esos elementos a esta caché durante el evento de instalación del Service Worker.

Por último, se registra una nueva ruta. Esta estrategia de Cache First administrará cualquier solicitud que sea una navegación de página, ya sea que se extraiga de la caché o de la red y, luego, se almacene en caché la respuesta.

Almacenamiento en caché de recursos

Con el almacenamiento previo en caché de rutas resuelto, es hora de volver a implementar el almacenamiento en caché para los recursos del sitio: CSS y JavaScript. Para ello, primero agrega StaleWhileRevalidate a tu importación de workbox-strategies y, luego, agrega el siguiente código al final de tu Service Worker:

// Set up asset cache
registerRoute(
  ({ request }) => ['style', 'script', 'worker'].includes(request.destination),
  new StaleWhileRevalidate({
    cacheName: 'asset-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  }),
);

Explicación

Esta ruta comienza por determinar si el tipo de solicitud es un diseño, una secuencia de comandos o un worker, lo que corresponde a CSS, JavaScript o Web Workers. Si es así, usa una estrategia de Stale While Revalidate, que intenta entregar contenido desde la caché primero y recurre a la red si no está disponible, mientras intenta actualizar la versión en la caché desde la red si es posible. Al igual que la estrategia de página, esta estrategia solo almacenará en caché las respuestas correctas.

4. Agrega una opción alternativa sin conexión

Una vez que se migró el service worker original a Workbox, hay una cosa más que se debe hacer para evitar que la AWP falle cuando no haya conexión: agregar una alternativa sin conexión.

Se pueden establecer alternativas sin conexión para cualquier elemento que no esté disponible cuando no haya conexión: páginas, fuentes, CSS, JavaScript, imágenes, etcétera. Como mínimo, se debe establecer una página de resguardo para todas las PWA, de modo que, si un usuario navega a una página que no está en la caché, permanezca dentro del contexto de tu app.

Las recetas de Workbox proporcionan una receta de resguardo sin conexión que se puede usar para hacer precisamente esto. Para usarlo, primero agrega offlineFallback a tu importación de workbox-recipes y, luego, agrega el siguiente código al final de tu Service Worker:

// Set up offline fallback
offlineFallback({
  pageFallback: '/offline.html',
});

Explicación

La receta de resguardo sin conexión configura una estrategia de solo caché que se calienta con los resguardos proporcionados. Luego, configura un controlador de captura predeterminado de Workbox, que captura cualquier solicitud de enrutamiento fallida (si no hay nada en la caché y no se puede acceder a nada en la red), extrae el contenido de los archivos pertinentes de la caché y lo devuelve como contenido siempre que la solicitud siga fallando.

5. ¡Felicitaciones!

Aprendiste a usar Workbox para configurar estrategias de almacenamiento en caché para rutas y proporcionar alternativas sin conexión para tu PWA.

El siguiente codelab de la serie es IndexedDB.