Como forçar um tempo limite de rede

Às vezes, você tem uma conexão de rede, mas ela é muito lenta ou é mentira que você está on-line. Em situações em que há um service worker entre eles, uma estratégia de armazenamento em cache que prioriza a rede pode levar muito tempo para receber uma resposta da rede, ou a solicitação trava, e os ícones de carregamento vão girar indefinidamente até que uma página de erro apareça.

Seja qual for a situação, há casos em que voltar à última resposta armazenada em cache para um recurso ou página após um determinado período seria preferível. Mas esse é outro problema com o qual o Workbox pode ajudar.

Como usar o networkTimeoutSeconds

É possível forçar um tempo limite para solicitações de rede ao usar as estratégias NetworkFirst ou NetworkOnly. Essas estratégias oferecem uma opção networkTimeoutSeconds, que especifica o número de segundos que o service worker precisa esperar pela resposta da rede antes de ela ser salva e retornar a última versão armazenada em 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);

O código acima instrui o service worker a liberar qualquer solicitação de navegação que prioriza a rede e usar a última versão em cache após três segundos. Quando usado com solicitações de navegação, garante acesso à última resposta em cache de qualquer página visitada anteriormente.

No entanto, e se a página que você está acessando não tiver uma resposta mais antiga no cache? Nesses casos, você pode estabelecer uma resposta substituta para uma página HTML off-line 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));

Isso funciona porque, ao usar networkTimeoutSeconds em uma estratégia NetworkFirst, seu gerenciador retornará uma resposta de erro se o tempo limite ocorrer e não houver uma correspondência de cache para o URL. Se isso acontecer, o plug-in da caixa de trabalho handlerDidError poderá fornecer uma resposta genérica como alternativa.

Quanto tempo é muito tempo para esperar?

Ao forçar um tempo limite para solicitações, especialmente solicitações de navegação, você quer encontrar o equilíbrio certo entre não deixar o usuário esperar muito tempo e não expirar muito rapidamente. Esperar muito tempo pode fazer com que os usuários em conexões lentas sejam rejeitadas antes que o tempo limite seja atingido. Tempo limite atingido muito rápido, e você pode acabar exibindo desnecessariamente conteúdo desatualizado a partir do cache.

A resposta certa é "depende". Se você estiver administrando um site, como um blog, e não atualizar o conteúdo com muita frequência, a resposta certa é errar por não esperar muito, já que o que está no cache provavelmente está "novo" o suficiente. No entanto, para sites e apps da Web mais interativos, pode ser melhor esperar um pouco mais e evitar a exibição excessiva de dados desatualizados no cache do service worker.

Se você estiver registrando métricas no campo, observe o 75o percentil das pontuações Tempo para primeiro byte (TTFB) e First Contentful Paint (FCP) para ter uma noção de onde pode haver tempos de espera mais longos para solicitações de navegação entre sua base de usuários. Isso pode lhe dar uma ideia de onde traçar os limites.