โดยค่าเริ่มต้น วงจรการทำงานของ Service Worker จะกําหนดให้เมื่อพบและติดตั้ง Service Worker ที่อัปเดตแล้ว แท็บที่เปิดอยู่ทั้งหมดที่โปรแกรมทำงานของบริการปัจจุบันควบคุมอยู่จะต้องปิดหรือมีการนำทางก่อนที่ Service Worker ที่อัปเดตจะเปิดใช้งานและเข้าควบคุม
ในหลายๆ กรณี การอนุญาตให้เกิดขึ้นในช่วงเวลาที่กําหนดก็ไม่เป็นไร แต่ในบางกรณีคุณอาจต้องแจ้งให้ผู้ใช้ทราบล่วงหน้าว่ามีการอัปเดต Service Worker ที่รอดําเนินการอยู่ จากนั้นทําให้กระบวนการเปลี่ยนไปใช้ Service Worker ใหม่เป็นไปโดยอัตโนมัติ โดยคุณจะต้องเพิ่มโค้ดบางอย่างในหน้าเว็บและ Service Worker ด้วย
โค้ดที่จะใส่ในหน้าเว็บของคุณ
โค้ดต่อไปนี้จะทำงานในองค์ประกอบ <script>
ในบรรทัดโดยใช้โมดูล JavaScript ที่นำเข้าจาก workbox-window
เวอร์ชันที่โฮสต์ใน CDN โปรแกรมนี้จะลงทะเบียน Service Worker โดยใช้ workbox-window
และจะตอบสนองหากโปรแกรมทำงานค้างในช่วงรอ เมื่อพบ Service Worker แล้ว โค้ดนี้จะแจ้งให้ผู้ใช้ทราบว่าเว็บไซต์มีเวอร์ชันที่อัปเดตแล้วให้ใช้งาน และแจ้งให้ผู้ใช้โหลดซ้ำ
<!-- This script tag uses JavaScript modules, so the proper `type` attribute value is required -->
<script type="module">
// This code sample uses features introduced in Workbox v6.
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');
let registration;
const showSkipWaitingPrompt = async (event) => {
// Assuming the user accepted the update, set up a listener
// that will reload the page as soon as the previously waiting
// service worker has taken control.
wb.addEventListener('controlling', () => {
// At this point, reloading will ensure that the current
// tab is loaded under the control of the new service worker.
// Depending on your web app, you may want to auto-save or
// persist transient state before triggering the reload.
window.location.reload();
});
// When `event.wasWaitingBeforeRegister` is true, a previously
// updated service worker is still waiting.
// You may want to customize the UI prompt accordingly.
// This code assumes your app has a promptForUpdate() method,
// which returns true if the user wants to update.
// Implementing this is app-specific; some examples are:
// https://open-ui.org/components/alert.research or
// https://open-ui.org/components/toast.research
const updateAccepted = await promptForUpdate();
if (updateAccepted) {
wb.messageSkipWaiting();
}
};
// Add an event listener to detect when the registered
// service worker has installed but is waiting to activate.
wb.addEventListener('waiting', (event) => {
showSkipWaitingPrompt(event);
});
wb.register();
}
</script>
หากพวกเขายอมรับ messageSkipWaiting()
จะบอกให้ Service Worker ที่รอเรียกใช้ self.skipWaiting()
ซึ่งหมายความว่าโปรแกรมจะเริ่มเปิดใช้งาน เมื่อเปิดใช้งานแล้ว Service Worker ใหม่จะควบคุมไคลเอ็นต์ที่มีอยู่ทั้งหมด ซึ่งทำให้เกิดเหตุการณ์ controlling
ใน workbox-window
เมื่อเกิดกรณีนี้ขึ้น หน้าเว็บปัจจุบันจะโหลดซ้ำโดยใช้เวอร์ชันล่าสุดของเนื้อหาที่จัดเก็บในแคชล่วงหน้าทั้งหมดและตรรกะการกำหนดเส้นทางใหม่ที่พบใน Service Worker ที่อัปเดตแล้ว
โค้ดที่จะใส่ใน Service Worker
เมื่อได้รับโค้ดจากส่วนก่อนหน้าในหน้าเว็บแล้ว คุณจะต้องเพิ่มโค้ดบางอย่างลงใน Service Worker เพื่อให้โปรแกรมทราบว่าจะต้องข้ามช่วงรอเมื่อใด หากคุณใช้ generateSW
จาก workbox-build
และได้ตั้งค่าตัวเลือก skipWaiting
เป็น false
(ค่าเริ่มต้น) แล้ว คุณก็พร้อมที่จะใช้งาน เนื่องจากโค้ดด้านล่างจะรวมอยู่ในไฟล์ Service Worker ที่คุณสร้างขึ้นโดยอัตโนมัติ
หากคุณกำลังเขียนโปรแกรมทำงานของบริการของคุณเอง โดยอาจใช้ร่วมกับเครื่องมือสร้างบิวด์ของ Workbox ในโหมด injectManifest
คุณจะต้องเพิ่มโค้ดต่อไปนี้ด้วยตนเอง
addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
การดำเนินการนี้จะรอฟังข้อความที่ส่งถึง Service Worker จาก workbox-window
ที่มีค่า type
เป็น SKIP_WAITING
และเมื่อเกิดเหตุการณ์นี้ ให้เรียก self.skipWaiting()
เมธอด messageSkipWaiting()
ใน workbox-window
ที่แสดงในตัวอย่างโค้ดก่อนหน้านี้มีหน้าที่ส่งข้อความนี้
คุณต้องการแสดงข้อความแจ้งหรือไม่
แต่นี่ไม่ใช่รูปแบบที่แอปพลิเคชันทุกตัวที่ติดตั้งใช้งาน Service Worker จะต้องทำตาม มีไว้สำหรับบางสถานการณ์ที่การไม่เปิดโอกาสให้โหลดหน้าเว็บซ้ำในการอัปเดตโปรแกรมทำงานของบริการอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด ไม่มีกฎที่ชัดเจนและเข้มงวดในการกำหนดว่าคุณควรแสดงข้อความแจ้งการโหลดซ้ำหรือไม่ แต่ก็อาจเหมาะสมบางสถานการณ์ดังต่อไปนี้
- คุณใช้การแคชล่วงหน้าอย่างเข้มงวด หากกังวลเกี่ยวกับเนื้อหาแบบคงที่ คุณอาจมีปัญหาในภายหลังในกรณีที่ใช้กลยุทธ์ที่เน้นเครือข่ายเป็นหลักหรือเฉพาะเครือข่ายเท่านั้นสำหรับคำขอการนำทาง แต่ใช้เนื้อหาแบบคงที่ที่โหลดแบบ Lazy Loading ซึ่งอาจทำให้เกิดสถานการณ์ต่างๆ ที่เนื้อหาซึ่งมีเวอร์ชันอาจมีการเปลี่ยนแปลง และ Service Worker ไม่ได้แคชเนื้อหาเหล่านั้นไว้ล่วงหน้า การเสนอปุ่มโหลดซ้ำที่นี่อาจหลีกเลี่ยงลักษณะการทำงานที่ไม่คาดคิดได้
- หากแสดง HTML ที่เก็บไว้ล่วงหน้า ในกรณีนี้ คุณควรอย่างเสนอปุ่มโหลดซ้ำในการอัปเดต Service Worker เนื่องจากการอัปเดต HTML นั้นจะไม่ได้รับการยอมรับจนกว่า Service Worker ที่อัปเดตจะเข้าควบคุม
- หากคุณไม่ได้อาศัยการแคชรันไทม์เป็นส่วนใหญ่ เมื่อแคชทรัพยากรขณะรันไทม์ คุณไม่จำเป็นต้องแจ้งให้ผู้ใช้ทราบว่าควรโหลดซ้ำ เมื่อมีการเปลี่ยนแปลงเนื้อหาที่มีเวอร์ชัน ระบบจะเพิ่มเนื้อหาดังกล่าวลงในแคชรันไทม์ในหลักสูตรที่ครบกำหนด ในกรณีที่คำขอการนำทางใช้กลยุทธ์แบบเครือข่ายเป็นหลักหรือเฉพาะเครือข่ายเท่านั้น
- เมื่อใช้กลยุทธ์ไม่อัปเดตขณะตรวจสอบใหม่ คุณอาจพิจารณาใช้โมดูล
workbox-broadcast-update
เพื่อแจ้งให้ผู้ใช้ทราบเกี่ยวกับการอัปเดตของโปรแกรมทำงานของบริการ
สิ่งที่คุณต้องแจ้งผู้ใช้เกี่ยวกับการอัปเดตของโปรแกรมทำงานของบริการจะขึ้นอยู่กับแอปพลิเคชันและข้อกำหนดที่ไม่ซ้ำกันของแอปพลิเคชันของคุณ หากคุณพบว่าผู้ใช้พบพฤติกรรมแปลกๆ เมื่อคุณเปิดใช้ Service Worker ใหม่ นั่นอาจเป็นสัญญาณที่ดีที่สุดว่าคุณควรแจ้งให้ผู้ใช้ทราบ