การแคชทรัพยากรระหว่างรันไทม์

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

ใน Workbox คุณสามารถจัดการการแคชรันไทม์สำหรับเนื้อหาโดยใช้โมดูล workbox-routing เพื่อจับคู่เส้นทาง และจัดการกลยุทธ์การแคชสำหรับเนื้อหาเหล่านั้นด้วยโมดูล workbox-strategies

กลยุทธ์การแคช

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

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

คุณสามารถใช้กลยุทธ์เหล่านี้เพื่อเลือกคำขอโดยใช้วิธีการของ workbox-routing

การใช้กลยุทธ์การแคชด้วยการจับคู่เส้นทาง

workbox-routing แสดงเมธอด registerRoute เพื่อจับคู่เส้นทางและจัดการเส้นทางด้วยกลยุทธ์การแคช registerRoute ยอมรับออบเจ็กต์ Route ซึ่งในทางกลับกันก็ยอมรับอาร์กิวเมนต์ 2 รายการ

  1. สตริง นิพจน์ทั่วไป หรือCallback ที่ตรงกันเพื่อระบุเกณฑ์การจับคู่เส้นทาง
  2. ตัวแฮนเดิลสำหรับเส้นทาง ซึ่งมักเป็นกลยุทธ์ที่ workbox-strategies มีให้

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

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

// sw.js import { registerRoute, Route } from 'workbox-routing'; import { CacheFirst } from 'workbox-strategies';  // A new route that matches same-origin image requests and handles // them with the cache-first, falling back to network strategy: const imageRoute = new Route(({ request, sameOrigin }) => {   return sameOrigin && request.destination === 'image' }, new CacheFirst());  // Register the new route registerRoute(imageRoute); 

การใช้แคชหลายรายการ

Workbox ช่วยให้คุณจัดเก็บคำตอบที่แคชไว้ไว้ในอินสแตนซ์ Cache แยกกันโดยใช้ตัวเลือก cacheName ที่มีอยู่ในกลยุทธ์แบบกลุ่ม

ในตัวอย่างต่อไปนี้ รูปภาพใช้กลยุทธ์ที่เก่าเกินไปขณะตรวจสอบความถูกต้องอีกครั้ง ขณะที่เนื้อหา CSS และ JavaScript จะใช้แคชเป็นหลักโดยกลับไปใช้กลยุทธ์เครือข่าย เส้นทางของเนื้อหาแต่ละรายการจะวางการตอบกลับลงในแคชแยกต่างหากด้วยการเพิ่มพร็อพเพอร์ตี้ cacheName

// sw.js import { registerRoute, Route } from 'workbox-routing'; import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';  // Handle images: const imageRoute = new Route(({ request }) => {   return request.destination === 'image' }, new StaleWhileRevalidate({   cacheName: 'images' }));  // Handle scripts: const scriptsRoute = new Route(({ request }) => {   return request.destination === 'script'; }, new CacheFirst({   cacheName: 'scripts' }));  // Handle styles: const stylesRoute = new Route(({ request }) => {   return request.destination === 'style'; }, new CacheFirst({   cacheName: 'styles' }));  // Register routes registerRoute(imageRoute); registerRoute(scriptsRoute); registerRoute(stylesRoute); 
ภาพหน้าจอของรายการอินสแตนซ์ Cache ในแท็บแอปพลิเคชันของเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome มีแคชแสดงอยู่ 3 รายการ ได้แก่ แคชรายการหนึ่งชื่อ "scripts" และอีกรายการชื่อ "styles" และอันสุดท้ายเรียกว่า "images"
เครื่องมือดูพื้นที่เก็บข้อมูลแคชในแผงแอปพลิเคชันของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome การตอบกลับสำหรับเนื้อหาประเภทต่างๆ จะเก็บไว้ในแคชแยกกัน

การตั้งค่าวันหมดอายุสำหรับรายการแคช

โปรดคำนึงถึงโควต้าพื้นที่เก็บข้อมูลเมื่อจัดการแคชของ Service Worker ExpirationPlugin ช่วยให้การบำรุงรักษาแคชง่ายขึ้นและจะเปิดเผยโดย workbox-expiration หากต้องการใช้งาน ให้ระบุพารามิเตอร์ในการกำหนดค่าสำหรับกลยุทธ์การแคช ดังนี้

// sw.js import { registerRoute, Route } from 'workbox-routing'; import { CacheFirst } from 'workbox-strategies'; import { ExpirationPlugin } from 'workbox-expiration';  // Evict image cache entries older thirty days: const imageRoute = new Route(({ request }) => {   return request.destination === 'image'; }, new CacheFirst({   cacheName: 'images',   plugins: [     new ExpirationPlugin({       maxAgeSeconds: 60 * 60 * 24 * 30,     })   ] }));  // Evict the least-used script cache entries when // the cache has more than 50 entries: const scriptsRoute = new Route(({ request }) => {   return request.destination === 'script'; }, new CacheFirst({   cacheName: 'scripts',   plugins: [     new ExpirationPlugin({       maxEntries: 50,     })   ] }));  // Register routes registerRoute(imageRoute); registerRoute(scriptsRoute); 

การปฏิบัติตามโควต้าพื้นที่เก็บข้อมูลอาจเป็นเรื่องซับซ้อน แนวทางปฏิบัติที่ดีคือพิจารณาผู้ใช้ที่อาจประสบปัญหาพื้นที่เก็บข้อมูล หรือต้องการใช้พื้นที่เก็บข้อมูลให้คุ้มค่าที่สุด คู่ ExpirationPlugin ของ Workbox จะช่วยให้บรรลุเป้าหมายได้

ข้อควรพิจารณาข้ามแหล่งที่มา

การโต้ตอบระหว่าง Service Worker กับเนื้อหาแบบข้ามต้นทางมีความแตกต่างจากเนื้อหาต้นทางเดียวกันอย่างมาก Cross-Origin Resource Share (CORS) เป็นสิ่งที่ซับซ้อน และความซับซ้อนนั้นรวมไปถึงวิธีจัดการทรัพยากรแบบข้ามต้นทางใน Service Worker ด้วย

การตอบสนองแบบทึบ

เมื่อส่งคำขอข้ามต้นทางในโหมด no-cors ระบบจะจัดเก็บการตอบกลับไว้ในแคชของ Service Worker และจะใช้โดยเบราว์เซอร์โดยตรงก็ได้ แต่เนื้อหาการตอบกลับตัวเอง จะอ่านผ่าน JavaScript ไม่ได้ วิธีนี้เรียกว่าการตอบสนองแบบทึบ

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

อย่าลืมเลือกใช้โหมด CORS

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

<link rel="stylesheet" href="https://example.com/path/to/style.css"> <img src="https://example.com/path/to/image.png"> 

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

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css"> <img crossorigin="anonymous" src="https://example.com/path/to/image.png"> 

โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อเส้นทางในแคชทรัพยากรย่อยของ Service Worker โหลดทรัพยากรย่อยขณะรันไทม์

กล่องงานอาจไม่แคชการตอบกลับที่ไม่ชัดเจน

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

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

หากคุณใช้กลยุทธ์การแคชอื่นและมีการตอบสนองแบบทึบ ช่องงานจะเตือนว่าการตอบกลับไม่ได้แคชเมื่ออยู่ในโหมดนักพัฒนาซอฟต์แวร์

บังคับให้แคชคำตอบที่ไม่ชัดเจน

หากแน่ใจจริงๆ ว่าต้องการแคชการตอบสนองแบบทึบแสงโดยใช้กลยุทธ์แบบแคชก่อนหรือแคชเท่านั้น ให้บังคับให้ Workbox ดำเนินการดังกล่าวโดยใช้โมดูล workbox-cacheable-response โดยทำดังนี้

import {Route, registerRoute} from 'workbox-routing'; import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies'; import {CacheableResponsePlugin} from 'workbox-cacheable-response';  const cdnRoute = new Route(({url}) => {   return url === 'https://cdn.google.com/example-script.min.js'; }, new CacheFirst({   plugins: [     new CacheableResponsePlugin({       statuses: [0, 200]     })   ] }))  registerRoute(cdnRoute); 

การตอบสนองแบบทึบและ navigator.storage API

เพื่อป้องกันไม่ให้ข้อมูลข้ามโดเมนรั่วไหล ระบบจึงเพิ่มระยะห่างจากขอบจำนวนมากในขนาดของการตอบสนองแบบทึบที่ใช้ในการคำนวณขีดจำกัดโควต้าพื้นที่เก็บข้อมูล การดําเนินการนี้จะส่งผลต่อวิธีที่ navigator.storage API รายงานโควต้าพื้นที่เก็บข้อมูล

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