Mengelola respons penggantian

Dalam situasi tertentu, Anda mungkin ingin respons fallback di-cache jika pengguna sedang offline. Mengimplementasikan fallback adalah alternatif untuk perilaku caching yang disediakan oleh strategi seperti network-first atau usang saat validasi ulang.

Penggantian merupakan respons generik satu ukuran untuk semua yang merupakan placeholder yang lebih baik daripada yang akan diberikan browser secara default saat permintaan gagal. Contohnya antara lain:

  • Alternatif untuk placeholder "gambar tidak ada".
  • Alternatif HTML untuk halaman standar "tidak ada koneksi jaringan yang tersedia".

Hanya halaman offline

Jika yang perlu Anda lakukan hanyalah menyediakan halaman HTML offline kustom, tetapi bukan yang lainnya, berikut ini resep dasar yang dapat Anda ikuti:

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

Kode di atas menggunakan setDefaultHandler untuk menggunakan strategi khusus jaringan sebagai default untuk semua rute. Kemudian, kode ini akan menjalankan urutan langkah offlineFallback untuk menyalurkan penggantian offline jika terjadi error. Resepnya mengasumsikan file HTML penggantian offline Anda akan diberi nama offline.html dan ditayangkan dari root server web.

Penggantian komprehensif

Setiap kali terjadi kegagalan jaringan atau cache tidak ditemukan, strategi caching yang ditawarkan oleh workbox-strategies akan menolak secara konsisten. Hal ini mendukung pola penetapan pengendali "catch" global untuk menangani kegagalan dalam fungsi pengendali tunggal, sehingga Anda dapat menawarkan penggantian yang berbeda untuk berbagai nilai request.destination.

Contoh berikut menggunakan urutan langkah warmStrategyCache dari workbox-recipes dan menetapkan pengendali tangkapan untuk menayangkan item yang di-cache sebelumnya di cache runtime. Namun, penggantian pra-cache mungkin lebih cocok untuk aplikasi Anda:

import {warmStrategyCache} from 'workbox-recipes';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate} from 'workbox-strategies';

// Fallback assets to cache
const FALLBACK_HTML_URL = '/offline.html';
const FALLBACK_IMAGE_URL = '/images/image-not-found.jpg';
const FALLBACK_STRATEGY = new CacheFirst();

// Warm the runtime cache with a list of asset URLs
warmStrategyCache({
  urls: [FALLBACK_HTML_URL, FALLBACK_IMAGE_URL],
  strategy: FALLBACK_STRATEGY,
});

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // The warmStrategyCache recipe is used to add the fallback assets ahead of
  // time to the runtime cache, and are served in the event of an error below.
  // Use `event`, `request`, and `url` to figure out how to respond, or
  // use request.destination to match requests for specific resource types.
  switch (request.destination) {
    case 'document':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_HTML_URL});

    case 'image':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_IMAGE_URL});

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

Selanjutnya, respons penggantian di-precache menggunakan injectManifest dengan alat build Workbox, dan berfungsi sebagai penggantian jika terjadi error dengan metode matchPrecache.

import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';

// Optional: use the injectManifest mode of one of the Workbox
// build tools to precache a list of URLs, including fallbacks.
precacheAndRoute(self.__WB_MANIFEST);

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // Fallback assets are precached when the service worker is installed, and are
  // served in the event of an error below. Use `event`, `request`, and `url` to
  // figure out how to respond, or use request.destination to match requests for
  // specific resource types.
  switch (request.destination) {
    case 'document':
      // FALLBACK_HTML_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_HTML_URL);

    case 'image':
      // FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_IMAGE_URL);

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

Contoh kasus penggunaan untuk penyiapan penggantian kedua adalah jika halaman di-cache sebelumnya, tetapi gambar (atau aset lainnya) yang diminta oleh halaman tidak. Halaman masih dapat dibaca dari cache saat pengguna sedang offline, tetapi placeholder penggantian atau fungsi alternatif dapat disediakan jika terjadi error jaringan.

Menghangatkan cache runtime

Workbox mempertahankan cache yang terpisah untuk cache precache dan cache runtime, dan mungkin ada situasi saat Anda ingin meng-cache sesuatu terlebih dahulu tanpa mengandalkan precache, karena update pada manifes precache akan mengharuskan Anda men-deploy pekerja layanan yang diperbarui.

Untuk menyiapkan cache runtime terlebih dahulu dengan aset, Anda dapat menggunakannya menggunakan urutan langkah warmStrategyCache dari workbox-recipes. Di balik layar, strategi ini memanggil Cache.addAll dalam peristiwa install pekerja layanan.

import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';

// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = [
  '/offline.html',
];

warmStrategyCache({urls, strategy});

Kesimpulan

Mengelola respons penggantian untuk permintaan yang gagal memerlukan sedikit usaha, tetapi dengan sedikit perencanaan sebelumnya, Anda dapat menyiapkan aplikasi web untuk menyediakan konten dan fungsionalitas tertentu saat pengguna sedang offline.