แพ็กเกจ workbox-window
คือชุดโมดูลที่มีไว้ทำงานใน
window
บริบท ซึ่ง
ก็คือภายในหน้าเว็บของคุณ ซึ่งช่วยส่งเสริมกล่องงานอื่นๆ
ที่เรียกใช้ในโปรแกรมทำงานของบริการ
ฟีเจอร์/เป้าหมายหลักของ workbox-window
มีดังนี้
- ทำให้ขั้นตอนการลงทะเบียนและการอัปเดตของ Service Worker ง่ายขึ้นด้วยการช่วยเหลือ นักพัฒนาซอฟต์แวร์สามารถระบุช่วงเวลาที่สำคัญที่สุดในวงจรของโปรแกรมทำงานของบริการ และทำให้ง่ายขึ้น เพื่อตอบสนองต่อช่วงเวลาเหล่านั้น
- เพื่อช่วยป้องกันไม่ให้นักพัฒนาแอปทำข้อผิดพลาดที่พบบ่อยที่สุด
- เพื่อช่วยให้สื่อสารกันได้ง่ายขึ้น ระหว่างโค้ดที่ทำงานใน Service Worker กับโค้ดที่ทำงานในหน้าต่าง
การนำเข้าและการใช้หน้าต่างงาน
จุดแรกเข้าหลักสำหรับแพ็กเกจ workbox-window
คือคลาส Workbox
และ
คุณสามารถนำเข้า URL ดังกล่าวในโค้ดจาก CDN ของเราหรือใช้รายการ
เครื่องมือการรวมกลุ่ม JavaScript
การใช้ CDN ของเรา
วิธีที่ง่ายที่สุดในการนำเข้าคลาส Workbox
ในเว็บไซต์ของคุณคือจาก CDN ของเรา
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
โปรดทราบว่าตัวอย่างนี้ใช้ <script type="module">
และคำสั่ง import
เพื่อ
โหลดชั้นเรียน Workbox
คุณอาจคิดว่าจำเป็นต้องเปลี่ยนข้อมูล
เพื่อทำให้โค้ดทำงานในเบราว์เซอร์รุ่นเก่า ซึ่งไม่ใช่ความจำเป็นจริงๆ
เบราว์เซอร์หลักทั้งหมดที่โปรแกรมทำงานสนับสนุนบริการยังรองรับโมดูล JavaScript แบบเนทีฟด้วย ดังนั้นจึงทำได้เต็มที่ แสดงโค้ดนี้ในทุกเบราว์เซอร์ได้ (เบราว์เซอร์รุ่นเก่าจะไม่สนใจโค้ดนี้)
กำลังโหลด Workbox ด้วย Bundler JavaScript
คุณไม่จำเป็นต้องใช้เครื่องมือใดๆ เลยในการใช้ workbox-window
แต่ถ้า
โครงสร้างพื้นฐานของการพัฒนา
มี Bundler อย่าง
Webpack หรือ Rollup ที่ใช้งานได้
ด้วยทรัพยากร Dependency npm คุณจะนําไปใช้เพื่อ
โหลด workbox-window
ขั้นตอนแรกคือ
ติดตั้ง
workbox-window
เป็นทรัพยากร Dependency สำหรับแอปพลิเคชันของคุณ:
npm install workbox-window
จากนั้นในไฟล์ JavaScript ของแอปพลิเคชัน import
ช่องงานโดย
อ้างอิงชื่อแพ็กเกจ workbox-window
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
หาก Bundler ของคุณรองรับการแยกโค้ดผ่านคำสั่งการนำเข้าแบบไดนามิก
คุณยังโหลด workbox-window
แบบมีเงื่อนไขได้ด้วย ซึ่งจะช่วยลด
ของแพ็กเกจหลักของหน้าเว็บ
แม้ว่า workbox-window
จะค่อนข้างเล็ก แต่ก็ไม่มีเหตุผล
จำเป็นต้องโหลดด้วยตรรกะแอปพลิเคชันหลักของเว็บไซต์
ในฐานะโปรแกรมทำงานของบริการ
โดยธรรมชาติแล้ว ถือว่าเป็นการปรับปรุงที่ก้าวหน้า
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
แนวคิดการรวมกลุ่มขั้นสูง
ไฟล์บิลด์จะต่างจากแพ็กเกจ Workbox ที่เรียกใช้ในโปรแกรมทำงานของบริการ
ที่อ้างอิงโดย workbox-window
main
และ
module
ช่องใน
package.json
แปลงเป็น ES5 ซึ่งทำให้เข้ากับ
เครื่องมือบิลด์ บางรายการที่ไม่อนุญาตให้นักพัฒนาซอฟต์แวร์แปลงข้อมูล
ทรัพยากร Dependency ของ node_module
หากระบบของบิลด์อนุญาตให้คุณแปลงทรัพยากร Dependency (หรือหากคุณ คุณควรนำเข้าโค้ด ไฟล์ต้นฉบับ แทนที่จะเป็นตัวแพ็กเกจ
ต่อไปนี้คือวิธีต่างๆ ในการนำเข้า Workbox
พร้อมด้วยคำอธิบายของ
สิ่งที่แต่ละชิ้นจะส่งคืน
// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');
// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';
// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';
ตัวอย่าง
เมื่อนำเข้าชั้นเรียน Workbox
แล้ว คุณจะใช้ชั้นเรียนเพื่อลงทะเบียนและ
โต้ตอบกับ Service Worker ตัวอย่างวิธีที่คุณอาจนำไปใช้ได้มีดังนี้
Workbox
ในแอปพลิเคชันของคุณ:
ลงทะเบียน Service Worker และแจ้งให้ผู้ใช้ทราบในครั้งแรกที่โปรแกรมทำงานของบริการ
โปรแกรมทำงานของบริการผู้ใช้เว็บแอปพลิเคชันจำนวนมากที่จะแคชเนื้อหาล่วงหน้าเพื่อให้แอปทำงานได้ ออฟไลน์เมื่อโหลดหน้าเว็บที่ตามมา การแจ้งข้อมูลในบางกรณีเป็นเรื่องสมเหตุสมผล ผู้ใช้ที่แอปนี้พร้อมใช้งานแบบออฟไลน์แล้ว
const wb = new Workbox('/sw.js');
wb.addEventListener('activated', event => {
// `event.isUpdate` will be true if another version of the service
// worker was controlling the page when this version was registered.
if (!event.isUpdate) {
console.log('Service worker activated for the first time!');
// If your service worker is configured to precache assets, those
// assets should all be available now.
}
});
// Register the service worker after event listeners have been added.
wb.register();
แจ้งให้ผู้ใช้ทราบหากโปรแกรมทำงานของบริการได้ติดตั้งแล้ว แต่ต้องรอการเปิดใช้งาน
เมื่อหน้าเว็บที่ควบคุมโดย Service Worker ที่มีอยู่ลงทะเบียนบริการใหม่ โดยค่าเริ่มต้นโปรแกรมทำงานของบริการจะไม่เปิดใช้งานจนกว่าไคลเอ็นต์ทั้งหมด ซึ่งควบคุมโดย Service Worker เริ่มต้น ได้ยกเลิกการโหลดอย่างสมบูรณ์
ซึ่งเป็นสาเหตุที่พบบ่อยที่ทำให้นักพัฒนาซอฟต์แวร์สับสน โดยเฉพาะอย่างยิ่งในกรณีที่ การโหลดหน้าเว็บปัจจุบันซ้ำจะไม่ทำให้ Service Worker ใหม่เปิดใช้งาน
เพื่อช่วยลดความสับสนและอธิบายให้ชัดเจนเมื่อเกิดเหตุการณ์นี้ขึ้น
ชั้นเรียน Workbox
มีเหตุการณ์ waiting
ที่คุณฟังได้:
const wb = new Workbox('/sw.js');
wb.addEventListener('waiting', event => {
console.log(
`A new service worker has installed, but it can't activate` +
`until all tabs running the current version have fully unloaded.`
);
});
// Register the service worker after event listeners have been added.
wb.register();
แจ้งเตือนผู้ใช้เกี่ยวกับการอัปเดตแคชจากแพ็กเกจ workbox-broadcast-update
แพ็กเกจ workbox-broadcast-update
เป็นวิธีที่ยอดเยี่ยมในการแสดงเนื้อหาจากแคช (เพื่อการนำส่งที่รวดเร็ว)
สามารถแจ้งให้ผู้ใช้ทราบถึงการอัปเดตเนื้อหานั้น (โดยใช้
กลยุทธ์ที่ไม่มีการอัปเดตขณะตรวจสอบความถูกต้องอีกครั้ง)
หากต้องการรับการอัปเดตเหล่านั้นจากหน้าต่าง คุณสามารถฟังเหตุการณ์ message
ของ
ประเภท CACHE_UPDATED
:
const wb = new Workbox('/sw.js');
wb.addEventListener('message', event => {
if (event.data.type === 'CACHE_UPDATED') {
const {updatedURL} = event.data.payload;
console.log(`A newer version of ${updatedURL} is available!`);
}
});
// Register the service worker after event listeners have been added.
wb.register();
ส่งรายการ URL ที่จะแคชให้กับโปรแกรมทำงานของบริการ
สำหรับบางแอปพลิเคชัน คุณสามารถทราบเนื้อหาทั้งหมดที่จำเป็นต้องมี มีการแคชล่วงหน้า ณ เวลาสร้าง แต่แอปพลิเคชันบางรายการแสดงหน้าเว็บที่แตกต่างกันโดยสิ้นเชิง ขึ้นอยู่กับ URL ที่ผู้ใช้เข้าชมเป็นอันดับแรก
สำหรับแอปในหมวดหมู่หลัง คุณควรแคชเฉพาะเนื้อหา
ที่ผู้ใช้ต้องการสำหรับหน้าหนึ่งๆ ที่เข้าชม เมื่อใช้
แพ็กเกจ workbox-routing
คุณสามารถ
ส่งรายการ URL เพื่อแคชให้กับเราเตอร์ของคุณ จากนั้นระบบจะแคช URL เหล่านั้นตาม
ตามกฎที่กำหนดไว้ในเราเตอร์เอง
ตัวอย่างนี้จะส่งรายการ URL ที่โหลดโดยหน้าเว็บไปยังเราเตอร์เมื่อใดก็ตามที่ มีการเปิดใช้งาน Service Worker ใหม่ โปรดทราบว่าคุณสามารถส่ง URL ทั้งหมด เนื่องจากมีเพียง ระบบจะแคช URL ที่ตรงกับเส้นทางที่กำหนดไว้ใน Service Worker ดังนี้
const wb = new Workbox('/sw.js');
wb.addEventListener('activated', event => {
// Get the current page URL + all resources the page loaded.
const urlsToCache = [
location.href,
...performance.getEntriesByType('resource').map(r => r.name),
];
// Send that list of URLs to your router in the service worker.
wb.messageSW({
type: 'CACHE_URLS',
payload: {urlsToCache},
});
});
// Register the service worker after event listeners have been added.
wb.register();
ช่วงเวลาที่สำคัญในวงจรของโปรแกรมทำงานของบริการ
วงจรชีวิตของโปรแกรมทำงานของบริการ นั้นเป็นเรื่องซับซ้อนและอาจเป็นเรื่องที่ท้าทายในการทำความเข้าใจ สาเหตุส่วนหนึ่งคือ มีความซับซ้อนมากจนต้องจัดการกับ กรณีปัญหาทั้งหมดสำหรับการใช้งานที่เป็นไปได้ทั้งหมด Service Worker (เช่น การลงทะเบียน Service Worker มากกว่า 1 โปรแกรม, การลงทะเบียน Service Worker ที่อยู่คนละเฟรม ลงทะเบียน Service Worker ชื่ออื่น เป็นต้น)
แต่นักพัฒนาซอฟต์แวร์ส่วนใหญ่ที่ใช้โปรแกรมทำงานของบริการ (Service Worker) ไม่ควรจะต้องกังวลเรื่อง ทั้งหมดนี้เพราะการใช้งานนั้นค่อนข้างง่าย นักพัฒนาแอปส่วนใหญ่ ลงทะเบียน Service Worker เพียง 1 รายการต่อการโหลดหน้าเว็บ 1 ครั้ง โดยบุคคลเหล่านั้นจะไม่เปลี่ยนชื่อโปรแกรมทำงานของบริการ ไฟล์ที่พวกเขาทำให้ใช้งานได้ในเซิร์ฟเวอร์
คลาส Workbox
ยอมรับมุมมองที่เรียบง่ายขึ้นสำหรับวงจรชีวิตของ Service Worker
โดยการแบ่งการลงทะเบียนโปรแกรมทำงานของบริการทั้งหมดออกเป็น 2 หมวดหมู่ ได้แก่
เป็น Service Worker ที่ลงทะเบียนแล้ว และ Service Worker ภายนอก
- Service Worker ที่จดทะเบียน: โปรแกรมทำงานของบริการที่เริ่มการติดตั้งเป็น
ผลลัพธ์ของอินสแตนซ์
Workbox
ที่เรียกใช้register()
หรือมีการใช้งานแล้ว Service Worker หากการเรียกใช้register()
ไม่ทริกเกอร์เหตุการณ์updatefound
ในการลงทะเบียน - โปรแกรมทำงานของบริการภายนอก: โปรแกรมทำงานของบริการที่เริ่มการติดตั้ง
โดยไม่ขึ้นอยู่กับอินสแตนซ์
Workbox
ที่เรียกใช้register()
โดยปกติ เกิดขึ้นเมื่อผู้ใช้เปิดเว็บไซต์เวอร์ชันใหม่ของคุณในอีกแท็บหนึ่ง เมื่อ เหตุการณ์มาจาก Service Worker ภายนอก ซึ่งเป็นisExternal
พร็อพเพอร์ตี้จะถูกตั้งค่าเป็นtrue
ด้วยคำนึงถึง Service Worker ทั้ง 2 ประเภท ต่อไปนี้คือรายละเอียด ช่วงเวลาที่สำคัญในวงจรของโปรแกรมทำงานของบริการ รวมถึงคำแนะนำของนักพัฒนาซอฟต์แวร์ สำหรับวิธีจัดการ
ครั้งแรกที่ติดตั้งโปรแกรมทำงานของบริการ
อาจต้องทำตามขั้นตอนที่ติดตั้ง Service Worker ในครั้งแรก แตกต่างจากวิธีจัดการการอัปเดตทั้งหมดในอนาคต
คุณแยกความแตกต่างระหว่างเวอร์ชันต่างๆ ได้ใน workbox-window
การติดตั้งและการอัปเดตในอนาคต โดยตรวจสอบพร็อพเพอร์ตี้ isUpdate
ใน
เหตุการณ์ต่อไปนี้ สำหรับการติดตั้งครั้งแรก isUpdate
จะ
false
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', event => {
if (!event.isUpdate) {
// First-installed code goes here...
}
});
wb.register();
เมื่อพบ Service Worker เวอร์ชันอัปเดต
เมื่อโปรแกรมทำงานของบริการใหม่เริ่มติดตั้ง แต่เวอร์ชันที่มีอยู่ยังใช้อยู่
ที่ควบคุมหน้านี้ พร็อพเพอร์ตี้ isUpdate
ของเหตุการณ์ต่อไปนี้ทั้งหมดจะ
เป็น true
วิธีที่คุณตอบสนองในสถานการณ์นี้มักจะแตกต่างจาก เนื่องจากคุณต้องจัดการเวลาและวิธีการที่ผู้ใช้จะได้รับการอัปเดตนี้
เมื่อพบ Service Worker ในเวอร์ชันที่ไม่คาดคิด
บางครั้งผู้ใช้จะเปิดเว็บไซต์ของคุณไว้ในแท็บเบื้องหลังเป็นเวลานาน พวกเขาอาจเปิดแท็บใหม่และไปที่เว็บไซต์ของคุณโดยไม่รู้ตัว มีเว็บไซต์ของคุณเปิดอยู่ในแท็บพื้นหลังอยู่แล้ว ในกรณีดังกล่าว ที่ไซต์จะทำงานพร้อมกันได้ 2 เวอร์ชัน และ จะนำเสนอปัญหาที่น่าสนใจบางอย่างแก่คุณในฐานะนักพัฒนาซอฟต์แวร์
ลองนึกถึงสถานการณ์ที่คุณมีแท็บ A ทำงานอยู่ เวอร์ชัน 1 ของเว็บไซต์และแท็บ B เวอร์ชัน 2 เมื่อโหลดแท็บ B แท็บ B จะเป็นตัวควบคุมโดยเวอร์ชันของบริการ ผู้ปฏิบัติงานที่ส่งด้วย v1 แต่หน้าเว็บแสดงผลโดยเซิร์ฟเวอร์ (ถ้าใช้ กลยุทธ์การแคชเครือข่ายเป็นอันดับแรก สำหรับคำขอการนำทาง) จะมีเนื้อหา v2 ทั้งหมดของคุณ
แต่นี่ไม่ใช่ปัญหาสำหรับแท็บ B เพราะเมื่อคุณเขียน v2 คุณก็รู้ว่าโค้ด v1 ทำงานอย่างไร อย่างไรก็ตาม อาจเป็น ของแท็บ A เนื่องจากโค้ด v1 ไม่สามารถคาดการณ์สิ่งที่ การเปลี่ยนแปลงโค้ด v2 ที่อาจเกิดขึ้น
workbox-window
จะช่วยกระจายวงจรการทำงานเพื่อช่วยจัดการสถานการณ์เหล่านี้
เหตุการณ์เมื่อตรวจพบการอัปเดตจาก "ภายนอก" Service Worker ซึ่ง
ภายนอกหมายถึงเวอร์ชันที่ไม่ใช่เวอร์ชัน Workbox
ปัจจุบัน
ลงทะเบียนอินสแตนซ์แล้ว
เมื่อใช้ Workbox v6 ขึ้นไป เหตุการณ์เหล่านี้จะมีค่าเท่ากับเหตุการณ์ที่บันทึกไว้
ข้างต้น ด้วยการเพิ่มพร็อพเพอร์ตี้ isExternal: true
ในแต่ละเหตุการณ์
ออบเจ็กต์ หากเว็บแอปพลิเคชันต้องใช้ตรรกะเฉพาะในการจัดการกับ
"ภายนอก" Service Worker คุณสามารถตรวจสอบพร็อพเพอร์ตี้นั้นในเครื่องจัดการเหตุการณ์
การหลีกเลี่ยงข้อผิดพลาดที่พบบ่อย
หนึ่งในฟีเจอร์ที่ Workbox มีประโยชน์มากที่สุดก็คือการบันทึกของนักพัฒนาซอฟต์แวร์ และ
โดยเฉพาะอย่างยิ่งสำหรับ workbox-window
เราทราบดีว่าการพัฒนาด้วยโปรแกรมทำงานของบริการมักจะทำให้เกิดความสับสน ซึ่งไม่ใช่เรื่องที่คุณคาดหวังไว้ อาจเป็นเรื่องยากที่จะรู้สาเหตุ
ตัวอย่างเช่น เมื่อคุณทำการเปลี่ยนแปลง Service Worker และโหลดหน้าเว็บซ้ำ คุณอาจไม่เห็นการเปลี่ยนแปลงนั้นในเบราว์เซอร์ สาเหตุที่เป็นไปได้มากที่สุดคือ เป็น Service Worker ยังรอเปิดใช้งานอยู่
แต่เมื่อลงทะเบียน Service Worker กับคลาส Workbox
คุณจะได้
ได้รับทราบเกี่ยวกับการเปลี่ยนแปลงสถานะอายุการใช้งานทั้งหมดใน Play Console
ช่วยแก้ปัญหาเกี่ยวกับสาเหตุที่ทำให้สิ่งต่างๆ ไม่เป็นอย่างที่คุณคาดหวัง
นอกจากนี้ ข้อผิดพลาดที่พบบ่อยซึ่งนักพัฒนาแอปทำเมื่อใช้โปรแกรมทำงานของบริการเป็นครั้งแรกคือ เพื่อลงทะเบียน Service Worker ใน ผิดขอบเขต
เพื่อช่วยป้องกันไม่ให้เกิดเหตุการณ์เช่นนี้ ชั้นเรียน Workbox
จะเตือนคุณหาก
หน้าที่ลงทะเบียนโปรแกรมทำงานของบริการไม่ได้อยู่ในขอบเขตของโปรแกรมทำงานของบริการนั้น จะ
เตือนคุณในกรณีที่ Service Worker ของคุณทำงานอยู่แต่ยังไม่
การควบคุมหน้านี้
การสื่อสารของ Windows to Service Worker
การใช้งาน Service Worker ขั้นสูงส่วนใหญ่จะเกี่ยวข้องกับการรับส่งข้อความจำนวนมากระหว่าง
Service Worker และหน้าต่าง ชั้นเรียน Workbox
ก็ช่วยเราในเรื่องนี้เช่นกันโดย
จะระบุเมธอด messageSW()
ซึ่งจะทำให้ postMessage()
อินสแตนซ์
Service Worker ที่ลงทะเบียนแล้วและรอการตอบกลับ
แม้ว่าคุณจะส่งข้อมูลไปยัง Service Worker ในรูปแบบใดก็ได้ แต่รูปแบบที่แชร์ แพ็กเกจกล่องงานทั้งหมดคือออบเจ็กต์ที่มี 3 พร็อพเพอร์ตี้ (2 รายการหลังคือ ไม่บังคับ):
ข้อความที่ส่งผ่านเมธอด messageSW()
จะใช้ MessageChannel
เพื่อให้ผู้รับ
สามารถตอบสนองต่อพวกเขาได้ หากต้องการตอบกลับข้อความที่โทรได้
event.ports[0].postMessage(response)
ใน Listener เหตุการณ์ข้อความ
เมธอด messageSW()
จะแสดงคำมั่นสัญญาว่าจะแก้ไข response
ใดก็ตาม
ที่คุณตอบกลับ
ต่อไปนี้เป็นตัวอย่างการส่งข้อความจากหน้าต่างไปยัง Service Worker และ
ในการตอบกลับ โค้ดบล็อกแรกคือ Listener ข้อความใน
Service Worker และบล็อกที่ 2 จะใช้คลาส Workbox
เพื่อส่ง
ข้อความและรอการตอบกลับ:
โค้ดใน sw.js:
const SW_VERSION = '1.0.0';
addEventListener('message', event => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
โค้ดใน main.js (ทำงานในหน้าต่าง):
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
การจัดการความไม่เข้ากันของเวอร์ชัน
ตัวอย่างด้านบนแสดงวิธีการตรวจสอบ Service Worker เวอร์ชันจากหน้าต่าง เราใช้ตัวอย่างนี้เนื่องจากเมื่อส่ง ไปมาระหว่างหน้าต่างกับโปรแกรมทำงานของบริการ ซึ่งเป็นสิ่งที่สำคัญ ที่ต้องทราบว่าโปรแกรมทำงานของบริการของคุณอาจไม่ได้ใช้รุ่นเดียวกัน ที่โค้ดของหน้าเว็บทำงานอยู่ และโซลูชันในการจัดการกับเรื่องนี้ จะแตกต่างกันไป ขึ้นอยู่กับว่าคุณแสดงหน้าเว็บแบบเครือข่ายเป็นอันดับแรกหรือไม่ หรือแบบใช้แคชเป็นหลัก
เครือข่ายก่อน
เมื่อแสดงเครือข่ายของหน้าเว็บเป็นอันดับแรก ผู้ใช้ของคุณจะได้รับ เวอร์ชันล่าสุดของ HTML จากเซิร์ฟเวอร์ของคุณ แต่ครั้งแรกที่ผู้ใช้ เข้าชมเว็บไซต์ของคุณอีกครั้ง (หลังจากที่คุณทำการอัปเดตแล้ว) HTML ที่ลูกค้าจะได้รับ เวอร์ชันล่าสุด แต่ Service Worker ที่ทำงานในเบราว์เซอร์ เวอร์ชันที่ติดตั้งก่อนหน้านี้ (อาจจะหลายเวอร์ชันกว่า)
คุณจำเป็นต้องเข้าใจความเป็นไปได้นี้เพราะถ้า JavaScript โหลด ตามหน้าเว็บเวอร์ชันปัจจุบัน จะส่งข้อความไปยัง รุ่นเก่าของ ของ Service Worker เวอร์ชันนั้นอาจไม่ทราบวิธีตอบสนอง (หรืออาจตอบสนองด้วย รูปแบบที่เข้ากันไม่ได้)
ดังนั้น ควรกำหนดเวอร์ชันโปรแกรมทำงานของบริการเสมอและตรวจสอบ เพื่อหาเวอร์ชันที่เข้ากันได้ก่อนที่จะทำงานสำคัญ
ตัวอย่างเช่น ในโค้ดข้างต้น หากเวอร์ชัน Service Worker แสดงผลตามเวอร์ชันดังกล่าว
การเรียกใช้ messageSW()
เก่ากว่าเวอร์ชันที่คาดไว้ โปรดรอสักครู่
จนกว่าจะพบการอัปเดต (ซึ่งควรเกิดขึ้นเมื่อคุณโทรหา register()
) ที่
คุณสามารถแจ้งผู้ใช้หรือการอัปเดต
ข้ามขั้นตอนการรอ
เพื่อเปิดใช้งาน Service Worker ใหม่ทันที
แคชก่อน
ซึ่งต่างจากเวลาที่คุณแสดงหน้าเว็บที่เน้นเครือข่ายเป็นหลัก เมื่อแสดงหน้าแคช
ก่อนอื่น คุณต้องรู้ว่า ในตอนแรกหน้าเว็บจะมีเวอร์ชันเดียวกับ
Service Worker ของคุณ (เพราะนั่นคือหน้าที่ของ Service Worker) และด้วยเหตุนี้จึงมีความปลอดภัย
เพื่อใช้ messageSW()
ทันที
อย่างไรก็ตาม หากพบ Service Worker เวอร์ชันอัปเดตและเปิดใช้งานแล้ว
เมื่อหน้าเว็บเรียกใช้ register()
(กล่าวคือ คุณตั้งใจข้ามขั้นตอนการรอ)
การส่งข้อความให้อีเมลอาจไม่ปลอดภัยอีกต่อไป
กลยุทธ์หนึ่งในการจัดการความเป็นไปได้นี้ก็คือการใช้รูปแบบการกำหนดเวอร์ชัน จะช่วยให้คุณสามารถแยกความแตกต่างระหว่างการอัปเดตที่ด่วนกับการอัปเดตที่ไม่เสียหาย และในกรณีของการอัปเดตด่วน คุณย่อมรู้ว่าการส่งข้อความถึง Service Worker แต่คุณต้องเตือนผู้ใช้ว่า และแนะนำให้โหลดซ้ำเพื่อรับการอัปเดต
ไม่ต้องรอตัวช่วย
แบบแผนการใช้งานทั่วไปสำหรับการรับส่งข้อความของ Windows to Service Worker คือการส่งข้อความ
{type: 'SKIP_WAITING'}
ข้อความเพื่อแนะนำโปรแกรมทำงานของบริการที่ติดตั้งอยู่แล้ว
ข้ามขั้นตอนการรอ
และเปิดใช้งาน
ตั้งแต่ Workbox v6 เป็นต้นไป คุณสามารถใช้เมธอด messageSkipWaiting()
เพื่อส่ง
{type: 'SKIP_WAITING'}
ข้อความไปยัง Service Worker ที่กำลังรอที่เชื่อมโยงกับ
การลงทะเบียน Service Worker ปัจจุบัน โมเดลจะไม่ดำเนินการใดๆ ถ้าไม่มีการตั้งค่า
กำลังรอโปรแกรมทำงานของบริการ
ประเภท
Workbox
คลาสที่ช่วยจัดการการลงทะเบียน การอัปเดต และของโปรแกรมทำงานของบริการ การตอบสนองต่อเหตุการณ์ในวงจรของโปรแกรมทำงานของบริการ
พร็อพเพอร์ตี้
-
เครื่องมือสร้าง
เป็นโมฆะ
สร้างอินสแตนซ์ Workbox ใหม่พร้อม URL ของสคริปต์และ Service Worker ตัวเลือก URL ของสคริปต์และตัวเลือกจะเหมือนกับที่ใช้เมื่อ ที่เรียกใช้ navigator.serviceWorker.register(scriptURL, ตัวเลือก)
ฟังก์ชัน
constructor
มีลักษณะดังนี้(scriptURL: string | TrustedScriptURL, registerOptions?: object) => {...}
-
scriptURL
string | TrustedScriptURL
สคริปต์ Service Worker ที่เชื่อมโยงกับอินสแตนซ์นี้ การใช้ รองรับ
TrustedScriptURL
-
registerOptions
ออบเจ็กต์ไม่บังคับ
-
returns
-
-
ใช้งาน
Promise<ServiceWorker>
-
กำลังควบคุม
Promise<ServiceWorker>
-
getSW
เป็นโมฆะ
แก้ไขด้วยการอ้างอิงไปยัง Service Worker ที่ตรงกับ URL ของสคริปต์ ของอินสแตนซ์นี้ทันทีที่พร้อมให้ใช้งาน
หากมีบริการที่ใช้งานอยู่หรือกำลังรอดำเนินการแล้ว ณ เวลาลงทะเบียน ที่มี URL ของสคริปต์ตรง จะถูกนำมาใช้ (โดยต้องรอ Service Worker มีความสำคัญเหนือกว่า Service Worker ที่ใช้งานอยู่หากทั้ง เนื่องจาก Service Worker ที่รออยู่จะมีการลงทะเบียนมากกว่า เมื่อเร็วๆ นี้) หากไม่มี Service Worker ที่ทำงานอยู่หรือกำลังรอจับคู่ในขณะลงทะเบียน สัญญาจะไม่ได้รับการแก้ไขจนกว่าจะพบและเริ่มต้นการอัปเดต โดยจะติดตั้งโปรแกรมทำงานของบริการ ณ จุดใด
ฟังก์ชัน
getSW
มีลักษณะดังนี้() => {...}
-
returns
Promise<ServiceWorker>
-
-
messageSW
เป็นโมฆะ
ส่งออบเจ็กต์ข้อมูลที่ส่งผ่านไปยัง Service Worker ที่ลงทะเบียนโดย อินสแตนซ์ (ผ่าน
workbox-window.Workbox#getSW
) และแก้ไข พร้อมคำตอบ (หากมี)คุณสามารถตั้งค่าการตอบกลับในตัวแฮนเดิลข้อความในตัวทำงานของบริการได้โดยดำเนินการดังนี้ จะโทรหา
event.ports[0].postMessage(...)
ซึ่งจะเป็นไปตามสัญญาmessageSW()
ส่งคืน ถ้าไม่ได้กำหนดการตอบสนองไว้ สัญญาจะ แก้ไขฟังก์ชัน
messageSW
มีลักษณะดังนี้(data: object) => {...}
-
ข้อมูล
ออบเจ็กต์
ออบเจ็กต์ที่จะส่งไปยัง Service Worker
-
returns
สัญญา<ไม่จำกัด>
-
-
messageSkipWaiting
เป็นโมฆะ
ส่งข้อความ
{type: 'SKIP_WAITING'}
ไปยัง Service Worker ที่ ขณะนี้อยู่ในสถานะwaiting
ที่เชื่อมโยงกับการจดทะเบียนปัจจุบันหากไม่มีการลงทะเบียนปัจจุบันหรือไม่มี Service Worker อยู่ใน
waiting
การเรียกใช้จะไม่มีผลฟังก์ชัน
messageSkipWaiting
มีลักษณะดังนี้() => {...}
-
รีจิสเตอร์
เป็นโมฆะ
ลงทะเบียน Service Worker สำหรับ URL และบริการของอินสแตนซ์นี้ ผู้ปฏิบัติงาน โดยค่าเริ่มต้น วิธีนี้จะหน่วงเวลาการลงทะเบียนจนกว่า หน้าต่างโหลดขึ้นมา
ฟังก์ชัน
register
มีลักษณะดังนี้(options?: object) => {...}
-
ตัวเลือก
ออบเจ็กต์ไม่บังคับ
-
ที่อยู่ติดๆ กัน
บูลีน ไม่บังคับ
-
-
returns
Promise<ServiceWorkerRegistration>
-
-
อัปเดต
เป็นโมฆะ
ตรวจหาการอัปเดตของ Service Worker ที่ลงทะเบียน
ฟังก์ชัน
update
มีลักษณะดังนี้() => {...}
-
returns
คำสัญญา<โมฆะ>
-
WorkboxEventMap
พร็อพเพอร์ตี้
-
เปิดอยู่
-
กำลังเปิดใช้งาน
-
กำลังควบคุม
-
ติดตั้งแล้ว
-
กำลังติดตั้ง
-
ข้อความ
-
ซ้ำซ้อน
-
กำลังรอ
WorkboxLifecycleEvent
พร็อพเพอร์ตี้
-
isExternal
บูลีน ไม่บังคับ
-
isUpdate
บูลีน ไม่บังคับ
-
originalEvent
กิจกรรม ไม่บังคับ
-
sw
ServiceWorker ไม่บังคับ
-
เป้าหมาย
WorkboxEventTarget ไม่บังคับ
-
ประเภท
typeOperator
WorkboxLifecycleEventMap
พร็อพเพอร์ตี้
-
เปิดอยู่
-
กำลังเปิดใช้งาน
-
กำลังควบคุม
-
ติดตั้งแล้ว
-
กำลังติดตั้ง
-
ซ้ำซ้อน
-
กำลังรอ
WorkboxLifecycleWaitingEvent
พร็อพเพอร์ตี้
-
isExternal
บูลีน ไม่บังคับ
-
isUpdate
บูลีน ไม่บังคับ
-
originalEvent
กิจกรรม ไม่บังคับ
-
sw
ServiceWorker ไม่บังคับ
-
เป้าหมาย
WorkboxEventTarget ไม่บังคับ
-
ประเภท
typeOperator
-
wasWaitingBeforeRegister
บูลีน ไม่บังคับ
WorkboxMessageEvent
พร็อพเพอร์ตี้
-
ข้อมูล
ใดๆ
-
isExternal
บูลีน ไม่บังคับ
-
originalEvent
กิจกรรม
-
ports
typeOperator
-
sw
ServiceWorker ไม่บังคับ
-
เป้าหมาย
WorkboxEventTarget ไม่บังคับ
-
ประเภท
"message"
เมธอด
messageSW()
workbox-window.messageSW(
sw: ServiceWorker,
data: object,
)
ส่งออบเจ็กต์ข้อมูลไปยัง Service Worker ผ่าน postMessage
และแก้ไขด้วย
คำตอบ (หากมี)
คุณสามารถตั้งค่าการตอบกลับในตัวแฮนเดิลข้อความในตัวทำงานของบริการได้โดยดำเนินการดังนี้
จะโทรหา event.ports[0].postMessage(...)
ซึ่งจะเป็นไปตามสัญญา
messageSW()
ส่งคืน ถ้าไม่ได้กำหนดการตอบสนองไว้ สัญญาว่าจะไม่
แก้ไข
พารามิเตอร์
-
sw
ServiceWorker
Service Worker ที่จะส่งข้อความถึง
-
ข้อมูล
ออบเจ็กต์
ออบเจ็กต์ที่จะส่งไปยัง Service Worker
การคืนสินค้า
-
สัญญา<ไม่จำกัด>