Offline fallback page with service worker

Nhiều năm trước, tôi đã thực hiện một số nghiên cứu về cách các ứng dụng gốc phản ứng với việc thiếu kết nối mạng. Mặc dù tôi đã mất liên kết đến phân tích (tôi có thể thề là trên Google+), câu chuyện bao quát là nhiều ứng dụng gốc gắn chặt với internet mà chúng chỉ cần từ chối hoạt động. Nghe có vẻ giống như rất nhiều ứng dụng web, điều khiến chúng khác biệt so với web là trải nghiệm vẫn là 'thương hiệu', Bart Simpson sẽ nói với bạn rằng bạn cần phải trực tuyến (ví dụ), và cho phần lớn các trải nghiệm web bạn nhận được 'Dino' (xem chrome: // dino).

Chúng tôi đã làm việc với Service Worker từ lâu và trong khi chúng tôi thấy ngày càng nhiều trang có các trang được kiểm soát bởi Worker, thì phần lớn các trang web thậm chí không có trải nghiệm dự phòng cơ bản khi mạng không có sẵn.

Tôi đã hỏi Jake, người bạn tốt của tôi nếu chúng tôi có bất kỳ hướng dẫn nào về cách xây dựng một trang dự phòng chung chung với giả định rằng bạn không muốn tạo ra trải nghiệm ngoại tuyến hoàn toàn đầu tiên, và trong vòng 10 phút anh ấy đã tạo ra nó. Check it out .

Để cho ngắn gọn, tôi đã dán mã bên dưới vì nó chỉ dài khoảng 20 dòng. Nó lưu trữ các tài sản ngoại tuyến, và sau đó với mỗi lần tìm nạp là 'điều hướng', nó sẽ xem nếu nó bị lỗi (vì mạng) và sau đó hiển thị trang ngoại tuyến thay cho nội dung gốc.

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

Đó là tất cả. Khi người dùng trực tuyến, họ sẽ thấy trải nghiệm mặc định.

Và khi người dùng ngoại tuyến, họ sẽ nhận được trang dự phòng.

Tôi thấy tập lệnh đơn giản này vô cùng mạnh mẽ và vâng, trong khi nó vẫn có thể được cải thiện, tôi tin rằng ngay cả một thay đổi đơn giản trong cách chúng ta nói với người dùng của mình khi có vấn đề với mạng có khả năng cải thiện cơ bản nhận thức của web cho người dùng trên toàn cầu.

** Cập nhật ** Jeffrey Posnick kinldy đã nhắc nhở tôi về việc sử dụng Navigation Preload để không phải chờ SW boot cho tất cả các yêu cầu, điều này đặc biệt quan trọng nếu bạn chỉ kiểm soát các yêu cầu mạng fails.

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.