Cómo forzar un tiempo de espera de la red

A veces tienes una conexión de red, pero esa conexión es demasiado lenta o la conexión te dice que estás en línea. En situaciones en las que un service worker está presente, una estrategia de almacenamiento en caché centrada en la red puede tardar demasiado tiempo en obtener una respuesta de la red, o bien la solicitud se bloquea (y los íconos giratorios de carga giran sin fin) hasta que veas una página de error.

Sin importar la situación, hay casos en los que sería preferible recurrir a la última respuesta almacenada en caché de un elemento o una página después de un período determinado, pero Workbox puede resolver otro problema.

Usa networkTimeoutSeconds

Se puede forzar un tiempo de espera para las solicitudes de red cuando se usan las estrategias NetworkFirst o NetworkOnly. Estas estrategias ofrecen una opción networkTimeoutSeconds, que especifica el número de segundos que el service worker debe esperar hasta que llegue la respuesta de la red antes de que salga del sistema y muestre la última versión almacenada en caché:

// sw.js
import { NetworkFirst } from 'workbox-strategies';
import { registerRoute, NavigationRoute } from 'workbox-routing';

// Only wait for three seconds before returning the last
// cached version of the requested page.
const navigationRoute = new NavigationRoute(new NetworkFirst({
  networkTimeoutSeconds: 3,
  cacheName: 'navigations'
}));

registerRoute(navigationRoute);

El código anterior le indica a tu service worker que salga de cualquier solicitud de navegación que priorice la red y que use la última versión almacenada en caché después de tres segundos. Cuando se usa con solicitudes de navegación, garantiza el acceso a la última respuesta almacenada en caché de cualquier página visitada anteriormente.

Sin embargo, ¿qué sucede si la página a la que accedes no tiene una respuesta anterior en la caché? En casos como ese, puedes establecer una respuesta de resguardo a una página HTML sin conexión genérica:

import {registerRoute, NavigationRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Hardcode the fallback cache name and the offline
// HTML fallback's URL for failed responses
const FALLBACK_CACHE_NAME = 'offline-fallback';
const FALLBACK_HTML = '/offline.html';

// Cache the fallback HTML during installation.
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(FALLBACK_CACHE_NAME).then((cache) => cache.add(FALLBACK_HTML)),
  );
});

// Apply a network-only strategy to navigation requests.
// If offline, or if more than five seconds pass before there's a
// network response, fall back to the cached offline HTML.
const networkWithFallbackStrategy = new NetworkOnly({
  networkTimeoutSeconds: 5,
  plugins: [
    {
      handlerDidError: async () => {
        return await caches.match(FALLBACK_HTML, {
          cacheName: FALLBACK_CACHE_NAME,
        });
      },
    },
  ],
});

// Register the route to handle all navigations.
registerRoute(new NavigationRoute(networkWithFallbackStrategy));

Esto funciona porque cuando usas networkTimeoutSeconds en una estrategia NetworkFirst, tu controlador mostrará una respuesta de error si se agota el tiempo de espera y no hay una coincidencia de caché para la URL. Si eso sucede, el complemento handlerDidError de Workbox puede proporcionar una respuesta genérica como resguardo.

¿Cuánto tiempo es demasiado tiempo para esperar?

Cuando fuerzas el tiempo de espera de las solicitudes, en especial las de navegación, debes encontrar el equilibrio adecuado entre no permitir que el usuario espere demasiado y no agotar el tiempo de espera demasiado rápido. Si esperas demasiado, podrías correr el riesgo de que los usuarios de conexiones lentas reboten antes de que se agote el tiempo de espera. El tiempo de espera es demasiado rápido, y es posible que entregues contenido inactivo de la caché de forma innecesaria.

La respuesta correcta es “Depende”. Si ejecutas un sitio como un blog y no actualizas el contenido con demasiada frecuencia, es probable que la respuesta correcta sea no esperar demasiado tiempo, ya que el contenido de la caché probablemente sea "actual". Sin embargo, en el caso de las apps y los sitios web más interactivos, es mejor esperar un poco más y evitar entregar con demasiada anticipación los datos obsoletos de la caché del service worker.

Si registras métricas en el campo, observa el percentil 75 de las puntuaciones de Tiempo hasta el primer byte (TTFB) y Primer procesamiento de imagen con contenido (FCP) para tener una idea de dónde podrían estar los tiempos de espera más largos para las solicitudes de navegación entre tu base de usuarios. Eso puede darte una idea sobre dónde trazar el límite.