Offline fallback page with service worker

Anos atrás, fiz algumas pesquisas sobre como os aplicativos nativos responderam à falta de conectividade de rede. Embora eu tenha perdido o link para a análise (eu poderia jurar que estava no Google+), a narrativa abrangente era que muitos aplicativos nativos estão inextricavelmente ligados à internet e que eles apenas se recusam a funcionar. Parece um monte de aplicativos web, o que os diferencia da web é que a experiência ainda era 'on-brand', Bart Simpson diria que você precisa estar online (por exemplo), e ainda para o Na grande maioria das experiências na web, você obtém um 'Dino' (veja chrome: // dino).

Estamos trabalhando no Service Worker há muito tempo e, embora vejamos cada vez mais sites com páginas controladas por um Service Worker, a grande maioria dos sites nem sequer tem uma experiência básica de fallback quando a rede não é acessível.

Eu perguntei ao meu bom amigo, Jake, se temos alguma orientação sobre como construir uma página genérica de retorno, supondo que você não queira criar uma primeira experiência totalmente off-line, e em 10 minutos ele a criou. Check it out .

Para simplificar, colei o código abaixo porque ele tem apenas 20 linhas. Ele armazena em cache os ativos off-line e, para cada busca que é uma busca de 'navegação', ela verifica se há erros (por causa da rede) e, em seguida, renderiza a página off-line no lugar do conteúdo original.

addEventListener('install', (event) => {
  event.waitUntil(async function() {
    const cache = await caches.open('static-v1');
    await cache.addAll(['offline.html', 'styles.css']);
  }());
});

// See https://developers.google.com/web/updates/2017/02/navigation-preload#activating_navigation_preload
addEventListener('activate', event => {
  event.waitUntil(async function() {
    // Feature-detect
    if (self.registration.navigationPreload) {
      // Enable navigation preloads!
      await self.registration.navigationPreload.enable();
    }
  }());
});

addEventListener('fetch', (event) => {
  const { request } = event;

  // Always bypass for range requests, due to browser bugs
  if (request.headers.has('range')) return;
  event.respondWith(async function() {
    // Try to get from the cache:
    const cachedResponse = await caches.match(request);
    if (cachedResponse) return cachedResponse;

    try {
      // See https://developers.google.com/web/updates/2017/02/navigation-preload#using_the_preloaded_response
      const response = await event.preloadResponse;
      if (response) return response;

      // Otherwise, get from the network
      return await fetch(request);
    } catch (err) {
      // If this was a navigation, show the offline page:
      if (request.mode === 'navigate') {
        return caches.match('offline.html');
      }

      // Otherwise throw
      throw err;
    }
  }());
});

Isso é tudo. Quando o usuário está online, ele verá a experiência padrão.

E quando o usuário estiver offline, ele receberá a página de fallback.

Eu acho este script simples incrivelmente poderoso, e sim, enquanto ele ainda pode ser melhorado, eu acredito que mesmo apenas uma simples mudança na maneira como falamos com nossos usuários quando há um problema com a rede tem a capacidade de melhorar fundamentalmente a percepção da web para usuários em todo o mundo.

** Atualização ** Jeffrey Posnick kinldy me lembrou sobre o uso do Pré-carregamento de Navegação para não ter que esperar pela inicialização do SW para todas as solicitações, isso é especialmente importante se você estiver controlando apenas solicitações de rede failed.

About Me: Paul Kinlan

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.