การจัดการการตอบกลับสำรอง

ในบางสถานการณ์ คุณอาจต้องการแคชการตอบกลับสำรองในกรณีที่ผู้ใช้ออฟไลน์ การใช้ข้อมูลสำรองเป็นทางเลือกหนึ่งแทนพฤติกรรมการแคชที่กลยุทธ์อย่างเช่น ให้ความสำคัญกับเครือข่ายเป็นอันดับแรกหรือไม่มีอัปเดตในขณะที่ตรวจสอบความถูกต้องอีกครั้ง

วิดีโอสำรองเป็นคำตอบทั่วไปที่ตอบโจทย์ได้ทุกข้อ เนื่องจากเป็นตัวยึดตำแหน่งที่ดีกว่าที่เบราว์เซอร์จะมีให้โดยค่าเริ่มต้นเมื่อคำขอล้มเหลว ตัวอย่างเช่น

  • ทางเลือกหนึ่งสำหรับ "รูปภาพหายไป" ตัวยึดตําแหน่ง
  • HTML ทางเลือกมาตรฐาน "ไม่มีการเชื่อมต่อเครือข่ายที่ใช้ได้"

หน้าออฟไลน์เท่านั้น

ถ้าคุณแค่ใส่หน้า HTML ออฟไลน์ที่กำหนดเอง แต่ไม่ต้องใส่เพิ่ม นี่คือสูตรพื้นฐานที่คุณสามารถทำตามได้

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

setDefaultHandler(new NetworkOnly());

offlineFallback();

โค้ดด้านบนใช้ setDefaultHandler เพื่อใช้กลยุทธ์เฉพาะเครือข่ายเป็นค่าเริ่มต้นสำหรับเส้นทางทั้งหมด จากนั้นจะเรียกใช้สูตร offlineFallback เพื่อแสดงทางเลือกสำรองแบบออฟไลน์ในกรณีที่เกิดข้อผิดพลาด โดยสูตรนี้จะถือว่าไฟล์ HTML สำรองแบบออฟไลน์จะตั้งชื่อเป็น offline.html และจะแสดงจากรูทของเว็บเซิร์ฟเวอร์

วิดีโอสำรองที่ครอบคลุม

เมื่อใดก็ตามที่เครือข่ายล้มเหลวหรือไม่พบแคช กลยุทธ์การแคชที่ workbox-strategies นำเสนอจะปฏิเสธอย่างสม่ำเสมอ ซึ่งเป็นการส่งเสริมรูปแบบการ "ดึงดูดความสนใจ" จากทั่วโลก ตัวแฮนเดิลเพื่อจัดการกับความล้มเหลวใดก็ตามในฟังก์ชันของตัวแฮนเดิลเดียว ซึ่งช่วยให้เสนอตัวเลือกสำรองสำหรับค่า request.destination ที่ต่างกันได้

ตัวอย่างต่อไปนี้ใช้สูตร warmStrategyCache จาก workbox-recipes และตั้งค่าตัวแฮนเดิลการจับเพื่อแสดงรายการที่แคชไว้ล่วงหน้าในแคชรันไทม์ อย่างไรก็ตาม วิดีโอสำรองของการแคชล่วงหน้าอาจเหมาะกับแอปพลิเคชันของคุณมากกว่า

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

ในขั้นตอนถัดไปนี้ ระบบจะแคชการตอบกลับสำรองล่วงหน้าโดยใช้ injectManifest กับเครื่องมือสร้างของ Workbox และทำหน้าที่เป็นวิดีโอสำรองในกรณีที่เกิดข้อผิดพลาดเมื่อใช้เมธอด 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();
  }
});

ตัวอย่างกรณีการใช้งานสำหรับการตั้งค่าสำรองที่ 2 คือหากมีการแคชหน้าเว็บไว้ล่วงหน้า แต่รูปภาพ (หรือเนื้อหาอื่นๆ) ที่หน้าเว็บขอไม่ได้มีการแคชไว้ ผู้ใช้จะยังอ่านหน้าเว็บได้จากแคชเมื่อผู้ใช้ออฟไลน์ แต่จะระบุตัวยึดตำแหน่งสำรองหรือฟังก์ชันการทำงานสำรองได้หากเกิดข้อผิดพลาดเกี่ยวกับเครือข่าย

การทำให้แคชรันไทม์อุ่นขึ้น

Workbox จะเก็บแคชแยกต่างหากสำหรับการแคชล่วงหน้าและแคชรันไทม์ และอาจมีสถานการณ์ที่คุณต้องการแคชข้อมูลบางอย่างล่วงหน้าโดยไม่ต้องอาศัยการแคชล่วงหน้า เนื่องจากการอัปเดตไฟล์ Manifest ของแคชล่วงหน้าจะทำให้คุณต้องทำให้ Service Worker ที่อัปเดตใช้งานได้

วิธีเตรียมแคชรันไทม์ล่วงหน้าด้วยเนื้อหาต่างๆ คุณสามารถทำได้โดยใช้สูตร warmStrategyCache จาก workbox-recipes เบื้องหลังการทำงาน กลยุทธ์นี้เรียกใช้ Cache.addAll ในเหตุการณ์ install ของโปรแกรมทำงานของบริการ

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

บทสรุป

การจัดการการตอบกลับสำรองสำหรับคำขอที่ล้มเหลวอาจต้องใช้งานสักหน่อย แต่เมื่อมีการวางแผนล่วงหน้าเล็กน้อย คุณสามารถตั้งค่าให้เว็บแอปมอบเนื้อหาและฟังก์ชันการทำงานในระดับหนึ่งเมื่อผู้ใช้ออฟไลน์ได้