Offline fallback page with service worker

Il y a des années, j'ai effectué des recherches sur la manière dont les applications natives répondaient au manque de connectivité réseau. Bien que j'ai perdu le lien avec l'analyse (je pourrais jurer que c'était sur Google+), le récit général était que de nombreuses applications natives sont inextricablement liées à Internet et refusent tout simplement de fonctionner. Cela ressemble à de nombreuses applications Web. Ce qui les différencie du Web, c’est que l’expérience était encore «sur la marque». Bart Simpson vous dirait que vous devez être en ligne (par exemple), et pourtant Dans la grande majorité des expériences Web, vous obtenez un 'Dino' (voir chrome: // dino).

Nous travaillons depuis longtemps sur Service Worker, et même si nous constatons que de plus en plus de sites ont des pages contrôlées par un technicien, la grande majorité des sites n’a même pas une expérience de repli de base lorsque le réseau n’est pas disponible. disponible.

J'ai demandé à mon bon ami Jake si nous avions des idées sur la façon de créer une page générique de repli, en partant du principe que vous ne souhaitiez pas créer une première expérience totalement hors ligne, et en 10 minutes, il l'avait créée. Check it out .

Par souci de brièveté, j'ai collé le code ci-dessous car il ne compte que 20 lignes environ. Il met en cache les ressources hors ligne. Ensuite, pour chaque extraction qui est une extraction de «navigation», il verra s'il y a une erreur (à cause du réseau), puis restituera la page hors connexion à la place du contenu d'origine.

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

C'est tout. Lorsque l'utilisateur est en ligne, il verra l'expérience par défaut.

Et lorsque l'utilisateur est hors ligne, il obtiendra la page de secours.

Je trouve ce script simple incroyablement puissant et, bien qu’il puisse encore être amélioré, j’estime que même un simple changement dans la manière dont nous parlons avec nos utilisateurs en cas de problème avec le réseau a la capacité de s’améliorer fondamentalement. la perception du Web pour les utilisateurs du monde entier.

** Mise à jour ** Jeffrey Posnick kinldy m'a rappelé l'utilisation du préchargement de navigation afin de ne pas attendre le démarrage de SW pour toutes les demandes. Cela est particulièrement important si vous ne contrôlez que les demandes réseau échouées.

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.