เนื้อหาบางอย่างในเว็บแอปพลิเคชันอาจมีการใช้งานไม่บ่อย มีขนาดใหญ่มาก หรือแตกต่างกันไปตามอุปกรณ์ของผู้ใช้ (เช่น รูปภาพที่ตอบสนองตามอุปกรณ์) หรือภาษา กรณีเหล่านี้คือกรณีที่การแคชล่วงหน้าอาจเป็นรูปแบบที่เข้ากันไม่ได้ และคุณควรใช้การแคชรันไทม์แทน
ใน Workbox คุณสามารถจัดการการแคชรันไทม์สำหรับเนื้อหาโดยใช้โมดูล workbox-routing
เพื่อจับคู่เส้นทาง และจัดการกลยุทธ์การแคชสำหรับเนื้อหาเหล่านั้นด้วยโมดูล workbox-strategies
กลยุทธ์การแคช
คุณสามารถจัดการเส้นทางส่วนใหญ่สำหรับเนื้อหาด้วยหนึ่งในกลยุทธ์การแคชในตัว ซึ่งกล่าวถึงรายละเอียดในเอกสารนี้ก่อนหน้านี้ แต่ยังมีประเด็นบางส่วนที่ควรพูดคุยกัน
- ไม่มีอัปเดตขณะตรวจสอบอีกครั้งจะใช้การตอบกลับที่แคชไว้สำหรับคำขอ หากมี และอัปเดตแคชในเบื้องหลังด้วยการตอบกลับจากเครือข่าย ดังนั้นหากไม่มีการแคชเนื้อหา ระบบจะรอการตอบสนองของเครือข่ายและนำไปใช้ วิธีนี้เป็นกลยุทธ์ที่ค่อนข้างปลอดภัยเนื่องจากจะอัปเดตรายการแคชที่อาศัยกลยุทธ์ดังกล่าวเป็นประจำ ข้อเสียคือระบบจะขอชิ้นงานจากเครือข่ายในเบื้องหลังเสมอ
- Network First จะพยายามรับการตอบสนองจากเครือข่ายก่อน หากได้รับการตอบกลับ ระบบจะส่งการตอบสนองนั้นไปยังเบราว์เซอร์และบันทึกลงในแคช หากขอเครือข่ายไม่สำเร็จ ระบบจะใช้การตอบสนองที่แคชไว้ล่าสุด ซึ่งเป็นการเปิดใช้การเข้าถึงเนื้อหาแบบออฟไลน์
- แคชก่อนจะตรวจสอบแคชเพื่อดูการตอบกลับก่อนและใช้แคชดังกล่าวหากมี หากคำขอไม่ได้อยู่ในแคช ระบบจะใช้เครือข่ายและเพิ่มการตอบสนองที่ถูกต้องลงในแคชก่อนส่งไปยังเบราว์เซอร์
- เครือข่ายเท่านั้น จะบังคับให้การตอบสนองมาจากเครือข่าย
- แคชเท่านั้นจะบังคับให้การตอบกลับมาจากแคช
คุณสามารถใช้กลยุทธ์เหล่านี้เพื่อเลือกคำขอโดยใช้วิธีการของ workbox-routing
การใช้กลยุทธ์การแคชด้วยการจับคู่เส้นทาง
workbox-routing
แสดงเมธอด registerRoute
เพื่อจับคู่เส้นทางและจัดการเส้นทางด้วยกลยุทธ์การแคช registerRoute
ยอมรับออบเจ็กต์ Route
ซึ่งในทางกลับกันก็ยอมรับอาร์กิวเมนต์ 2 รายการ
- สตริง นิพจน์ทั่วไป หรือCallback ที่ตรงกันเพื่อระบุเกณฑ์การจับคู่เส้นทาง
- ตัวแฮนเดิลสำหรับเส้นทาง ซึ่งมักเป็นกลยุทธ์ที่
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);
การตั้งค่าวันหมดอายุสำหรับรายการแคช
โปรดคำนึงถึงโควต้าพื้นที่เก็บข้อมูลเมื่อจัดการแคชของ 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 เมกะไบต์ คุณควรคำนึงถึงเรื่องนี้เมื่อพิจารณาจำนวนการตอบกลับแบบทึบที่ต้องการแคช เนื่องจากอาจทำให้เกินโควต้าพื้นที่เก็บข้อมูลได้เร็วกว่าที่คาดไว้มาก