Forzare un timeout di rete

A volte può capitare che la connessione di rete sia disponibile, ma che sia troppo lenta o che la connessione dichiari di essere online. In situazioni di questo tipo, in cui è presente un service worker, una strategia di memorizzazione nella cache incentrata sulla rete potrebbe richiedere troppo tempo per ricevere una risposta dalla rete oppure la richiesta si blocca e le rotelline di caricamento girino all'infinito finché non viene visualizzata una pagina di errore.

Qualunque sia la situazione, ci sono casi in cui sarebbe preferibile ricorrere all'ultima risposta memorizzata nella cache per una risorsa o una pagina dopo un determinato periodo di tempo, un altro problema per cui Workbox può essere d'aiuto.

In uso: networkTimeoutSeconds

È possibile forzare un timeout per le richieste di rete quando si utilizzano le strategie NetworkFirst o NetworkOnly. Queste strategie offrono un'opzione networkTimeoutSeconds che specifica il numero di secondi che il service worker deve attendere prima che arrivi la risposta di rete prima che si esca e restituisca l'ultima versione memorizzata nella cache:

// 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);

Il codice riportato sopra indica al service worker di saltare qualsiasi richiesta di navigazione network-first e di utilizzare l'ultima versione memorizzata nella cache dopo tre secondi. Quando utilizzata con le richieste di navigazione, garantisce l'accesso all'ultima risposta memorizzata nella cache di qualsiasi pagina visitata in precedenza.

Tuttavia, che cosa succede se la pagina a cui stai accedendo non contiene una risposta precedente nella cache? In questi casi, puoi stabilire una risposta di riserva a una pagina HTML offline generica:

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));

Questo accade perché quando utilizzi networkTimeoutSeconds in una strategia NetworkFirst, il gestore restituirà una risposta di errore se si verifica il timeout e non esiste una corrispondenza cache per l'URL. In tal caso, il plug-in handlerDidError Workbox può fornire una risposta generica come alternativa.

Quanto è troppo lungo aspettare?

Quando imponi un timeout per le richieste, in particolare per le richieste di navigazione, devi trovare il giusto equilibrio tra non consentire all'utente di attendere troppo a lungo e non timeout troppo rapidamente. Attendi troppo a lungo, potresti rischiare che gli utenti con connessioni lente non rimbalzano prima che si verifichi il timeout. Se si verifica un timeout troppo rapido, potresti finire per pubblicare inutilmente contenuti obsoleti dalla cache.

La risposta giusta è "dipende". Se gestisci un sito come un blog e non aggiorni troppo spesso i contenuti, la risposta giusta probabilmente è sbagliare per non aspettare troppo, dato che qualsiasi cosa si trova nella cache probabilmente è abbastanza aggiornata. Tuttavia, per i siti web e le app web più interattivi, potrebbe essere preferibile attendere un po' più a lungo ed evitare di fornire dati obsoleti dalla cache del service worker con troppa entusiasmo.

Se registri le metriche sul campo, dai un'occhiata al 75° percentile dei punteggi di Time to First Byte (TTFB) e First Contentful Paint (FCP) per avere un'idea di dove potrebbero essere tempi di attesa più lunghi per le richieste di navigazione nella tua base utenti. Questo potrebbe darti informazioni utili su dove tracciare il limite.