Offline fallback page with service worker

何年も前に、ネイティブアプリケーションがネットワーク接続の欠如にどのように対応したかについて調査しました。私は分析へのリンクを失いましたが(Google+にあると誓うことができます)、多くのネイティブアプリケーションはインターネットに密接に結び付けられているため、機能を拒否することができます。多くのWebアプリのように思えますが、それらはWebとは一線を画したものですが、経験はまだ「オンブランド」であったということです。大部分のWebエクスペリエンスでは、「Dino」が表示されます(chrome:// dinoを参照)。

Service Workerには長い間取り組んできましたが、Service Workerによってページが制御されるサイトがますます増えている一方で、ネットワークが機能していないときには、ほとんどのサイトで基本的なフォールバックの経験がありません利用可能です。

私は私たちの良い友達Jakeに、あなたが完全にオフラインで最初のエクスペリエンスを作りたくないという仮定の下で一般的なフォールバックページをどのように作り上げるかについてのガイダンスがあるかと尋ねました。 Check it out

説明を簡潔にするために、コードの長さは約20行にすぎないので、以下に貼り付けました。オフラインアセットをキャッシュし、「ナビゲーション」フェッチであるすべてのフェッチについて、エラーが発生したかどうか(ネットワークが原因で)を確認し、元のコンテンツの代わりにオフラインページをレンダリングします。

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

それがすべてです。ユーザーがオンラインのとき、彼らはデフォルトの経験を見るでしょう。

ユーザーがオフラインのときは、フォールバックページが表示されます。

私はこの単純なスクリプトが信じられないほど強力であることに気付きました、そして、それはまだ改善することができますが、ネットワークに問題があるときにユーザーに話す方法の単純な変更さえ根本的に改善する能力を持つ世界中のユーザーに対するWebの認識。

更新 Jeffrey Posnick kinldyは、すべてのリクエストに対してSWの起動を待つ必要がないようにナビゲーションプリロードを使用することを思い出しました。これは、失敗したネットワークリクエストのみを制御している場合に特に重要です。

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.