เนื้อหาบางอย่างในเว็บแอปพลิเคชันอาจใช้ไม่บ่อยนัก มีขนาดใหญ่มาก หรือแตกต่างกันตามอุปกรณ์ (เช่น รูปภาพที่ปรับเปลี่ยนตามอุปกรณ์) หรือภาษาของผู้ใช้ ซึ่งเป็นกรณีที่การแคชล่วงหน้าอาจเป็นรูปแบบต่อต้าน และคุณควรใช้การแคชรันไทม์แทน
ใน Workbox คุณจะจัดการการแคชรันไทม์สำหรับเนื้อหาได้โดยใช้โมดูล workbox-routing
เพื่อจับคู่เส้นทาง และจัดการกลยุทธ์การแคชเนื้อหาด้วยโมดูล workbox-strategies
กลยุทธ์การแคช
คุณสามารถจัดการเส้นทางส่วนใหญ่สำหรับเนื้อหาด้วยหนึ่งในกลยุทธ์การแคชในตัว มีคำอธิบายอย่างละเอียดอยู่ในช่วงต้นของเอกสารนี้ แต่เราขอสรุปข้อมูลสั้นๆ ดังนี้
- ไม่มีอัปเดตขณะตรวจสอบความถูกต้องอีกครั้งจะใช้การตอบกลับที่แคชไว้สำหรับคำขอ (หากมี) และอัปเดตแคชในเบื้องหลังด้วยการตอบกลับจากเครือข่าย ดังนั้นหากชิ้นงานไม่ได้แคช ชิ้นงานจะรอการตอบสนองของเครือข่ายและใช้ชิ้นงานนั้น กลยุทธ์นี้ค่อนข้างปลอดภัยเนื่องจากอัปเดตแคชที่ใช้แคชเป็นประจำ ข้อเสียก็คือ แอปจะขอเนื้อหาจากเครือข่ายในเบื้องหลังเสมอ
- Network First จะพยายามรับการตอบสนองจากเครือข่ายก่อน หากได้รับการตอบกลับ ระบบจะส่งการตอบกลับดังกล่าวไปยังเบราว์เซอร์และบันทึกลงในแคช หากคำขอเครือข่ายไม่สำเร็จ ระบบจะใช้การตอบสนองที่แคชไว้ล่าสุด ซึ่งจะเปิดใช้การเข้าถึงเนื้อหาแบบออฟไลน์ได้
- Cache First ตรวจสอบแคชสำหรับการตอบสนองก่อนและใช้หากมี หากคำขอไม่ได้อยู่ในแคช ระบบจะใช้เครือข่ายนั้น แล้วเพิ่มการตอบสนองที่ถูกต้องลงในแคชก่อนที่จะส่งไปยังเบราว์เซอร์
- เครือข่ายเท่านั้น บังคับให้การตอบกลับมาจากเครือข่าย
- แคชเท่านั้น บังคับให้การตอบกลับมาจากแคช
คุณสามารถใช้กลยุทธ์เหล่านี้เพื่อเลือกคำขอโดยใช้วิธีที่ workbox-routing
มีให้
การใช้กลยุทธ์การแคชกับการจับคู่เส้นทาง
workbox-routing
แสดงเมธอด registerRoute
เพื่อจับคู่เส้นทางและจัดการโดยใช้กลยุทธ์การแคช registerRoute
ยอมรับออบเจ็กต์ Route
ซึ่งก็ยอมรับอาร์กิวเมนต์ 2 รายการดังนี้
- สตริง นิพจน์ทั่วไป หรือโค้ดเรียกกลับที่ตรงกันเพื่อระบุเกณฑ์การจับคู่เส้นทาง
- เครื่องจัดการสำหรับเส้นทาง โดยทั่วไปจะเป็นกลยุทธ์ที่
workbox-strategies
ให้บริการ
แนะนำให้ใช้โค้ดเรียกกลับเพื่อจับคู่กับเส้นทาง เนื่องจากให้ออบเจ็กต์บริบทที่ประกอบด้วยออบเจ็กต์ 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);
![ภาพหน้าจอของรายการอินสแตนซ์แคชในแท็บแอปพลิเคชันเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome ระบบแสดงแคชที่แตกต่างกัน 3 แบบ ได้แก่ แคชที่ตั้งชื่อว่า "scripts" อีกรูปหนึ่งชื่อว่า "styles" และอันสุดท้ายชื่อว่า 'images'](https://developer.chrome.com/static/docs/workbox/caching-resources-during-runtime/image/a-screenshot-a-list-cac-bdd2858b485be.png?authuser=5&hl=th)
การตั้งค่าวันหมดอายุสำหรับรายการแคช
โปรดระวังโควต้าพื้นที่เก็บข้อมูลเมื่อจัดการแคชของ 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 Shared (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 เมกะไบต์ โปรดคำนึงถึงเรื่องนี้เมื่อกำหนดจำนวนคำตอบที่ไม่ชัดเจนที่ต้องการแคช เนื่องจากคุณอาจเกินโควต้าพื้นที่เก็บข้อมูลเร็วกว่าที่คาดไว้มาก