วงจรของโปรแกรมทำงานของบริการเป็นส่วนที่ซับซ้อนที่สุด หากคุณไม่รู้ว่ามันพยายามทำอะไรและประโยชน์ที่ได้รับ คุณสามารถรู้สึกว่ามันกำลังต่อสู้คุณอยู่ แต่เมื่อคุณทราบวิธีการทำงานแล้ว คุณก็สามารถส่งการอัปเดตที่ราบรื่นและไม่สร้างความรำคาญแก่ผู้ใช้ โดยผสมผสานรูปแบบที่ดีที่สุดของเว็บและเนทีฟ
นี่จะเป็นข้อมูลเจาะลึก แต่หัวข้อย่อยที่ตอนต้นของแต่ละส่วนจะพูดถึงสิ่งที่คุณจำเป็นต้องทราบเกือบทั้งหมด
ความตั้งใจ
วัตถุประสงค์ของวงจรคือ
- ทำให้การทำงานออฟไลน์เป็นหลักเป็นไปได้
- อนุญาตให้โปรแกรมทำงานของบริการใหม่สามารถเตรียมตัวให้พร้อมโดยไม่ขัดจังหวะการทำงานของโปรแกรมปัจจุบัน
- ตรวจสอบว่า Service Worker (หรือไม่มี Service Worker) คนเดิมควบคุมหน้าในขอบเขตได้
- ตรวจสอบว่าเว็บไซต์ทำงานพร้อมกันเพียงเวอร์ชันเดียว
ข้อสุดท้ายนั้นสำคัญมากๆ หากไม่มีโปรแกรมทำงานของบริการ ผู้ใช้จะโหลดแท็บหนึ่งไปยังเว็บไซต์ แล้วเปิดอีกแท็บในภายหลังได้ ซึ่งอาจส่งผลให้เว็บไซต์ 2 เวอร์ชันทำงานในเวลาเดียวกัน บางครั้งสิ่งนี้ก็ใช้ได้ แต่ถ้าจัดการกับพื้นที่เก็บข้อมูล คุณอาจพบว่าแท็บ 2 แท็บมีความคิดเห็นที่แตกต่างกันอย่างมากในการจัดการพื้นที่เก็บข้อมูลที่ใช้ร่วมกัน ซึ่งอาจส่งผลให้เกิดข้อผิดพลาด หรือที่แย่กว่านั้นคือข้อมูลสูญหาย
Service Worker รายแรก
เคล็ดลับโดยสรุปมีดังนี้
- เหตุการณ์
install
เป็นเหตุการณ์แรกที่ Service Worker ได้รับ และจะเกิดขึ้นเพียงครั้งเดียว - สัญญาณบอกสถานะที่ส่งไปยัง
installEvent.waitUntil()
จะส่งสัญญาณแจ้งระยะเวลาและความสำเร็จหรือความล้มเหลวของการติดตั้งของคุณ - โปรแกรมทำงานของบริการจะไม่ได้รับเหตุการณ์ เช่น
fetch
และpush
จนกว่าจะติดตั้งเสร็จสมบูรณ์และเปลี่ยนสถานะเป็น "ใช้งานอยู่" - โดยค่าเริ่มต้น การดึงข้อมูลของหน้าเว็บจะไม่ผ่าน Service Worker เว้นแต่คำขอหน้าเว็บจะผ่านโปรแกรมทำงานของบริการ คุณจึงต้องรีเฟรชหน้านี้เพื่อดูผลของ Service Worker
clients.claim()
สามารถลบล้างค่าเริ่มต้นนี้และควบคุมหน้าเว็บที่ไม่มีการควบคุมได้
ใช้ HTML นี้:
<!DOCTYPE html>
An image will appear here in 3 seconds:
<script>
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered!', reg))
.catch(err => console.log('Boo!', err));
setTimeout(() => {
const img = new Image();
img.src = '/dog.svg';
document.body.appendChild(img);
}, 3000);
</script>
โปรแกรมจะลงทะเบียน Service Worker และเพิ่มรูปภาพสุนัขหลังผ่านไป 3 วินาที
นี่คือ Service Worker sw.js
:
self.addEventListener('install', event => {
console.log('V1 installing…');
// cache a cat SVG
event.waitUntil(
caches.open('static-v1').then(cache => cache.add('/cat.svg'))
);
});
self.addEventListener('activate', event => {
console.log('V1 now ready to handle fetches!');
});
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// serve the cat SVG from the cache if the request is
// same-origin and the path is '/dog.svg'
if (url.origin == location.origin && url.pathname == '/dog.svg') {
event.respondWith(caches.match('/cat.svg'));
}
});
แคชรูปภาพแมวและแสดงเมื่อมีคำขอสำหรับ /dog.svg
อย่างไรก็ตาม หากคุณเรียกใช้ตัวอย่างข้างต้น คุณจะเห็นสุนัขในครั้งแรกที่โหลดหน้าเว็บ กดรีเฟรช แล้วคุณจะเห็นแมว
ขอบเขตและการควบคุม
ขอบเขตเริ่มต้นของการลงทะเบียน Service Worker คือ ./
ที่สัมพันธ์กับ URL ของสคริปต์ ซึ่งหมายความว่าหากคุณลงทะเบียน Service Worker ที่ //example.com/foo/bar.js
จะมีขอบเขตเริ่มต้นเป็น //example.com/foo/
เราเรียกเพจ ผู้ปฏิบัติงาน และผู้ปฏิบัติงานที่แชร์ร่วมกันว่า clients
Service Worker ของคุณควบคุมได้เฉพาะไคลเอ็นต์ที่อยู่ในขอบเขตเท่านั้น เมื่อไคลเอ็นต์ได้รับการ "ควบคุม" แล้ว ระบบจะดึงข้อมูลของไคลเอ็นต์ผ่าน Service Worker ในขอบเขต คุณตรวจสอบได้ว่ามีการควบคุมไคลเอ็นต์ผ่าน navigator.serviceWorker.controller
ซึ่งจะเป็นค่าว่างหรืออินสแตนซ์ของ Service Worker หรือไม่
ดาวน์โหลด แยกวิเคราะห์ และดำเนินการ
ระบบจะดาวน์โหลดโปรแกรมทำงานของบริการแรกเมื่อคุณเรียกใช้ .register()
หากสคริปต์ไม่สามารถดาวน์โหลด แยกวิเคราะห์ หรือแสดงข้อผิดพลาดในการดำเนินการครั้งแรก สัญญาการลงทะเบียนจะปฏิเสธ และระบบจะทิ้งโปรแกรมทำงานของบริการ
เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome แสดงข้อผิดพลาดในคอนโซลและในส่วนโปรแกรมทำงานของบริการของแท็บแอปพลิเคชัน:
![ข้อผิดพลาดแสดงขึ้นในแท็บเครื่องมือสำหรับนักพัฒนาเว็บใน Service Worker](https://web.dev/static/articles/service-worker-lifecycle/image/error-displayed-service.png?authuser=5&hl=th)
ติดตั้ง
เหตุการณ์แรกที่ Service Worker ได้รับคือ install
ระบบจะทริกเกอร์ทริกเกอร์นี้เมื่อผู้ปฏิบัติงานทำงาน และจะเรียกใช้เพียง 1 ครั้งต่อ Service Worker เท่านั้น หากคุณแก้ไขสคริปต์ของ Service Worker เบราว์เซอร์จะพิจารณาว่าเป็นโปรแกรมทำงานของบริการอย่างอื่น และจะได้รับเหตุการณ์ install
ของตัวเอง ฉันจะพูดถึงรายละเอียดเกี่ยวกับการอัปเดตในภายหลัง
เหตุการณ์ install
คือโอกาสในการแคชทุกอย่างที่คุณต้องการก่อนที่จะควบคุมไคลเอ็นต์ได้ คำมั่นสัญญาที่คุณส่งให้ event.waitUntil()
จะทำให้เบราว์เซอร์ทราบเวลาที่ติดตั้งเสร็จสมบูรณ์และทราบว่าติดตั้งสำเร็จหรือไม่
หากคำมั่นสัญญาของคุณปฏิเสธ จะส่งสัญญาณว่าติดตั้งไม่สำเร็จและเบราว์เซอร์จะกำจัดโปรแกรมทำงานของบริการออกไป ควบคุมลูกค้าไม่ได้ ซึ่งหมายความว่าเราสามารถอาศัย cat.svg
ที่มีอยู่ในแคชในเหตุการณ์ fetch
ได้ ต้องพึ่งพากัน
เปิดใช้งาน
เมื่อโปรแกรมทำงานของบริการพร้อมควบคุมไคลเอ็นต์และจัดการเหตุการณ์ด้านฟังก์ชัน เช่น push
และ sync
คุณจะได้รับเหตุการณ์ activate
แต่ไม่ได้หมายความว่าระบบจะควบคุมหน้าเว็บที่ .register()
ได้
ครั้งแรกที่คุณโหลดการสาธิต แม้จะมีการส่งคำขอ dog.svg
ไว้หลังจากที่ Service Worker เปิดใช้งานไปแล้ว แต่โปรแกรมก็จะไม่จัดการคำขอ และคุณยังเห็นภาพของสุนัขอยู่ ค่าเริ่มต้นคือความสอดคล้อง หากหน้าเว็บโหลดโดยไม่มีโปรแกรมทำงานของบริการ ทรัพยากรย่อยของหน้านั้นจะไม่เช่นกัน หากคุณโหลดการสาธิตเป็นครั้งที่ 2 (กล่าวคือ รีเฟรชหน้าเว็บ) ระบบจะควบคุมการสาธิตนั้น ทั้งหน้าเว็บและรูปภาพจะเข้าสู่เหตุการณ์ fetch
และคุณจะเห็นแมวแทน
clients.claim
คุณสามารถควบคุมไคลเอ็นต์ที่ไม่มีการควบคุมได้โดยเรียกใช้ clients.claim()
ภายใน Service Worker ของคุณเมื่อมีการเปิดใช้งานแล้ว
นี่คือการสาธิตรูปแบบหนึ่งด้านบนซึ่งเรียกใช้ clients.claim()
ในเหตุการณ์ activate
คุณควรเห็นแมวในครั้งแรก ฉันพูดว่า "ควร" เพราะนี่เป็นเรื่องจังหวะเวลา คุณจะเห็นแมวเฉพาะเมื่อโปรแกรมทำงานของบริการเปิดใช้งานและ clients.claim()
มีผลก่อนที่รูปภาพจะพยายามโหลด
หากคุณใช้ Service Worker เพื่อโหลดหน้าต่างไปจากที่โหลดผ่านเครือข่าย clients.claim()
อาจสร้างปัญหาได้เนื่องจากโปรแกรมทำงานของบริการจะควบคุมไคลเอ็นต์บางรายการที่โหลดโดยไม่มีโปรแกรมนี้
กำลังอัปเดตโปรแกรมทำงานของบริการ
เคล็ดลับโดยสรุปมีดังนี้
- และจะอัปเดตหากเกิดเหตุการณ์ต่อไปนี้ขึ้น
- การนำทางไปยังหน้าในขอบเขต
- เหตุการณ์ที่ใช้งานได้ เช่น
push
และsync
เว้นแต่จะมีการตรวจสอบการอัปเดตภายใน 24 ชั่วโมงก่อนหน้า - การเรียกใช้
.register()
เฉพาะเมื่อ URL ของ Service Worker มีการเปลี่ยนแปลง อย่างไรก็ตาม คุณควรหลีกเลี่ยงการเปลี่ยน URL ของผู้ปฏิบัติงาน
- เบราว์เซอร์ส่วนใหญ่ รวมถึง Chrome 68 ขึ้นไปจะไม่สนใจส่วนหัวการแคชเมื่อตรวจหาการอัปเดตสคริปต์ Service Worker ที่ลงทะเบียนไว้เป็นค่าเริ่มต้น โปรแกรมดังกล่าวยังคงปฏิบัติตามส่วนหัวของการแคชเมื่อดึงข้อมูลทรัพยากรที่โหลดภายใน Service Worker ผ่าน
importScripts()
คุณลบล้างลักษณะการทำงานเริ่มต้นนี้ได้โดยตั้งค่าตัวเลือกupdateViaCache
เมื่อลงทะเบียน Service Worker - ระบบจะถือว่าโปรแกรมทำงานของบริการ (Service Worker) ได้รับการอัปเดตหากมีไบต์ต่างจากที่เบราว์เซอร์มีอยู่แล้ว (เรากำลังขยายระยะเวลาให้รวมถึงสคริปต์/โมดูลที่นำเข้าด้วย)
- Service Worker ที่อัปเดตจะเปิดตัวควบคู่ไปกับโปรแกรมทำงานที่มีอยู่ และรับเหตุการณ์
install
ของตัวเอง - หากผู้ปฏิบัติงานใหม่มีรหัสสถานะที่ใช้งานไม่ได้ (เช่น 404) แยกวิเคราะห์ไม่สำเร็จ แสดงข้อผิดพลาดระหว่างดำเนินการ หรือปฏิเสธระหว่างการติดตั้ง ผู้ปฏิบัติงานใหม่จะหายไป แต่ผู้ปฏิบัติงานปัจจุบันยังคงทำงานอยู่
- เมื่อติดตั้งสำเร็จแล้ว ผู้ปฏิบัติงานที่อัปเดตแล้วจะ
wait
จนกว่าผู้ปฏิบัติงานที่มีอยู่จะควบคุมไคลเอ็นต์ 0 รายการ (โปรดทราบว่าไคลเอ็นต์จะทับซ้อนกันระหว่างการรีเฟรช) self.skipWaiting()
ป้องกันการรอ ซึ่งหมายความว่าโปรแกรมทำงานของบริการจะเปิดใช้งานทันทีที่ติดตั้งเสร็จ
สมมติว่าเราเปลี่ยนสคริปต์โปรแกรมทำงานของบริการให้ตอบกลับด้วยรูปม้าแทนที่จะเป็นรูปแมว
const expectedCaches = ['static-v2'];
self.addEventListener('install', event => {
console.log('V2 installing…');
// cache a horse SVG into a new cache, static-v2
event.waitUntil(
caches.open('static-v2').then(cache => cache.add('/horse.svg'))
);
});
self.addEventListener('activate', event => {
// delete any caches that aren't in expectedCaches
// which will get rid of static-v1
event.waitUntil(
caches.keys().then(keys => Promise.all(
keys.map(key => {
if (!expectedCaches.includes(key)) {
return caches.delete(key);
}
})
)).then(() => {
console.log('V2 now ready to handle fetches!');
})
);
});
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// serve the horse SVG from the cache if the request is
// same-origin and the path is '/dog.svg'
if (url.origin == location.origin && url.pathname == '/dog.svg') {
event.respondWith(caches.match('/horse.svg'));
}
});
ลองดูการสาธิตข้างต้น คุณควรจะเห็นภาพแมวอยู่ เนื่องจาก...
ติดตั้ง
โปรดทราบว่าฉันได้เปลี่ยนชื่อแคชจาก static-v1
เป็น static-v2
แล้ว ซึ่งหมายความว่าฉันตั้งค่าแคชใหม่ได้โดยไม่ต้องเขียนทับข้อมูลในแคชปัจจุบันที่ Service Worker เดิมยังคงใช้งานอยู่
รูปแบบนี้จะสร้างแคชเฉพาะเวอร์ชัน ซึ่งคล้ายกับเนื้อหาที่แอปที่มาพร้อมเครื่องจะรวมเข้ากับไฟล์ปฏิบัติการ คุณอาจมีแคชที่ไม่ได้เจาะจงเวอร์ชัน เช่น avatars
กำลังรอ
หลังจากติดตั้งสำเร็จแล้ว โปรแกรมทำงานของบริการที่อัปเดตจะหน่วงเวลาการเปิดใช้งานจนกว่าโปรแกรมทำงานของบริการที่มีอยู่จะไม่ควบคุมไคลเอ็นต์อีกต่อไป สถานะนี้เรียกว่า "กำลังรอ" และเป็นวิธีที่เบราว์เซอร์จะดูแลให้มีโปรแกรมทำงานของบริการเพียงเวอร์ชันเดียวที่ทำงานอยู่ในแต่ละครั้ง
หากเรียกใช้การสาธิตที่อัปเดตแล้ว คุณควรจะเห็นภาพแมว เนื่องจากผู้ปฏิบัติงาน V2 ยังไม่ได้เปิดใช้งาน คุณจะเห็น Service Worker ใหม่รออยู่ในแท็บ "แอปพลิเคชัน" ของเครื่องมือสำหรับนักพัฒนาเว็บดังนี้
![เครื่องมือสำหรับนักพัฒนาเว็บแสดง Service Worker ใหม่กำลังรอดำเนินการ](https://web.dev/static/articles/service-worker-lifecycle/image/devtools-showing-service-22927cf1663bf.png?authuser=5&hl=th)
แม้ว่าคุณจะเปิดการสาธิตเพียงแท็บเดียว แต่การรีเฟรชหน้าก็ไม่เพียงพอที่จะให้เวอร์ชันใหม่ทำงานแทน ซึ่งเป็นเพราะวิธีการไปยังส่วนต่างๆ ของเบราว์เซอร์ เมื่อคุณไปยังส่วนต่างๆ หน้าปัจจุบันจะไม่หายไปจนกว่าจะได้รับส่วนหัวของการตอบกลับแล้ว แม้ว่าหน้าปัจจุบันจะยังคงอยู่หากการตอบกลับมีส่วนหัว Content-Disposition
ซึ่งทำให้เกิดความซ้ำซ้อนนี้ Service Worker ปัจจุบันจึงควบคุมไคลเอ็นต์เสมอในระหว่างการรีเฟรช
ในการรับการอัปเดต ให้ปิดหรือออกจากแท็บทั้งหมดโดยใช้ Service Worker ปัจจุบัน จากนั้น เมื่อไปที่การสาธิตอีกครั้ง คุณจะเห็นม้า
รูปแบบนี้จะคล้ายกับการอัปเดตของ Chrome การอัปเดต Chrome จะดาวน์โหลดในเบื้องหลัง แต่จะไม่มีผลจนกว่า Chrome จะรีสตาร์ท ในระหว่างนี้ คุณยังสามารถใช้เวอร์ชันปัจจุบันต่อไปได้โดยไม่มีการหยุดชะงัก อย่างไรก็ตาม ข้อนี้จะยุ่งยากในระหว่างการพัฒนา แต่เครื่องมือสำหรับนักพัฒนาเว็บมีวิธีต่างๆ ที่จะทำให้ง่ายขึ้น ซึ่งเราจะอธิบายต่อไปในบทความนี้
เปิดใช้งาน
การดำเนินการนี้จะเริ่มทำงานเมื่อ Service Worker เดิมไม่ทำงาน และ Service Worker คนใหม่จะควบคุมไคลเอ็นต์ได้ เวลานี้เป็นเวลาที่เหมาะสมในการทำสิ่งที่คุณทำไม่ได้ขณะที่ผู้ปฏิบัติงานคนเก่ายังมีการใช้งานอยู่ เช่น การย้ายข้อมูลฐานข้อมูลและการล้างแคช
ในเดโมข้างต้น ฉันเก็บรายการแคชที่คาดว่าจะมีอยู่ และในเหตุการณ์ activate
ฉันจะนำแคชอื่นๆ ออก ซึ่งจะนำแคชเก่าของ static-v1
ออก
หากคุณส่งสัญญาให้ event.waitUntil()
ระบบจะบัฟเฟอร์เหตุการณ์ด้านการทำงาน (fetch
, push
, sync
ฯลฯ) จนกว่าสัญญาจะได้รับการแก้ไข ดังนั้นเมื่อเหตุการณ์ fetch
เริ่มทำงาน การเปิดใช้งานก็จะเสร็จสมบูรณ์
ข้ามขั้นตอนการรอ
ช่วงรอหมายความว่าคุณเรียกใช้เว็บไซต์เพียงเวอร์ชันเดียวพร้อมกัน แต่หากไม่ต้องการใช้ฟีเจอร์ดังกล่าว คุณสามารถทำให้ Service Worker ใหม่เปิดใช้งานได้เร็วขึ้นโดยโทรหา self.skipWaiting()
การดำเนินการนี้จะทำให้โปรแกรมทำงานของบริการของคุณเลิกใช้ผู้ปฏิบัติงานที่ใช้งานอยู่ในปัจจุบัน และเปิดใช้งานตัวเองทันทีที่ผู้ปฏิบัติงานดังกล่าวเข้าสู่ระยะรอ (หรือทันทีหากผู้ปฏิบัติงานนั้นอยู่ในขั้นรอแล้ว) โดยไม่ได้ทำให้ผู้ปฏิบัติงานของคุณข้ามการติดตั้ง เพียงแค่รอ
คุณไม่จำเป็นต้องโทรหา skipWaiting()
ตราบใดที่เป็นการโทรระหว่างหรือก่อนที่จะรอ เป็นเรื่องปกติที่จะเรียกสิ่งนี้ในเหตุการณ์ install
:
self.addEventListener('install', event => {
self.skipWaiting();
event.waitUntil(
// caching etc
);
});
แต่คุณอาจต้องเรียกใช้เป็นผลลัพธ์ของ postMessage()
สำหรับโปรแกรมทำงานของบริการ เช่นเดียวกับ คุณต้องการskipWaiting()
ติดตามการโต้ตอบของผู้ใช้
นี่คือการสาธิตที่ใช้ skipWaiting()
คุณจะเห็นภาพวัวโดยไม่ต้องเดินออกจากหน้าไป เช่นเดียวกับ clients.claim()
เครื่องมือนี้เป็นการแข่งขัน ดังนั้นคุณจะเห็นเฉพาะวัวเมื่อ Service Worker ใหม่ดึงข้อมูล ติดตั้ง และเปิดใช้งานก่อนที่หน้าเว็บจะพยายามโหลดรูปภาพ
อัปเดตด้วยตนเอง
อย่างที่ได้กล่าวไปแล้ว เบราว์เซอร์จะตรวจหาการอัปเดตโดยอัตโนมัติหลังจากการนำทางและเหตุการณ์การทำงาน แต่คุณสามารถเรียกใช้การอัปเดตด้วยตนเองได้เช่นกัน
navigator.serviceWorker.register('/sw.js').then(reg => {
// sometime later…
reg.update();
});
หากคุณคาดว่าผู้ใช้จะใช้เว็บไซต์ของคุณเป็นเวลานานโดยไม่มีการโหลดซ้ำ คุณอาจต้องโทรหา update()
เป็นช่วงเวลา (เช่น รายชั่วโมง)
หลีกเลี่ยงการเปลี่ยน URL ของสคริปต์ Service Worker
หากคุณได้อ่านโพสต์เกี่ยวกับแนวทางปฏิบัติแนะนำในการแคชแล้ว คุณอาจพิจารณากำหนด URL ที่ไม่ซ้ำกันให้กับโปรแกรมทำงานของบริการแต่ละเวอร์ชันได้ อย่าทำสิ่งนี้! แนวทางนี้มักเป็นแนวทางปฏิบัติที่ไม่ดีสำหรับโปรแกรมทำงานของบริการ เพียงอัปเดตสคริปต์ที่ตำแหน่งปัจจุบัน
ซึ่งอาจนำคุณไปสู่ปัญหาดังนี้
index.html
ได้ลงทะเบียนsw-v1.js
เป็น Service Workersw-v1.js
จะแคชและแสดงindex.html
เพื่อให้ทำงานแบบออฟไลน์ก่อนเป็นอันดับแรก- คุณอัปเดต
index.html
เพื่อให้มีการลงทะเบียนsw-v2.js
ใหม่และเงาของคุณ
หากดำเนินการข้างต้น ผู้ใช้จะไม่ได้รับ sw-v2.js
เนื่องจาก sw-v1.js
แสดง index.html
เวอร์ชันเก่าจากแคช คุณได้เตรียมตัวให้พร้อมสำหรับการอัปเดตโปรแกรมทำงานของบริการเพื่ออัปเดตโปรแกรมทำงานของบริการแล้ว อิจฉา
แต่สำหรับการสาธิตข้างต้น เราได้เปลี่ยน URL ของโปรแกรมทำงานของบริการ เพื่อการสาธิต คุณสามารถสลับระหว่างเวอร์ชันต่างๆ ได้ ผมไม่ใช่สิ่งที่จะทำในเวอร์ชันที่ใช้งานจริง
ทำให้การพัฒนาเป็นเรื่องง่าย
วงจรชีวิตของโปรแกรมทำงานของบริการสร้างขึ้นโดยคำนึงถึงผู้ใช้เป็นหลัก แต่ระหว่างการพัฒนานั้นค่อนข้างยุ่งยาก โชคดีที่เรามีเครื่องมือบางอย่างที่จะช่วยคุณได้:
อัปเดตเมื่อโหลดซ้ำ
อันนี้ชอบสุดเลย
![เครื่องมือสำหรับนักพัฒนาเว็บแสดง "อัปเดตเมื่อโหลดซ้ำ"](https://web.dev/static/articles/service-worker-lifecycle/image/devtools-showing-update-b22b12af7d1df.png?authuser=5&hl=th)
ซึ่งจะเปลี่ยนวงจรให้เป็นมิตรกับนักพัฒนาซอฟต์แวร์ การนำทางแต่ละรายการจะทำสิ่งต่อไปนี้
- ดึงข้อมูล Service Worker อีกครั้ง
- ติดตั้งเป็นเวอร์ชันใหม่แม้ว่าจะเป็นไบต์ตรงกัน ซึ่งหมายความว่าเหตุการณ์
install
จะทำงานและอัปเดตแคช - ข้ามขั้นตอนการรอเพื่อให้โปรแกรมทำงานของบริการใหม่เปิดใช้งาน
- ไปยังส่วนต่างๆ ของหน้าเว็บ
ซึ่งหมายความว่าคุณจะได้รับการอัปเดตในการนำทางแต่ละครั้ง (รวมถึงการรีเฟรช) โดยไม่ต้องโหลดซ้ำ 2 ครั้งหรือปิดแท็บ
ไม่ต้องรอ
![เครื่องมือสำหรับนักพัฒนาเว็บแสดง "ข้ามระหว่างรอ"](https://web.dev/static/articles/service-worker-lifecycle/image/devtools-showing-skip-wa-6591b8f145395.png?authuser=5&hl=th)
หากมีพนักงานรออยู่ คุณสามารถกด "ข้ามการรอ" ในเครื่องมือสำหรับนักพัฒนาเว็บเพื่อเลื่อนขั้นเป็น "ใช้งานอยู่" ได้ทันที
Shift-โหลดซ้ำ
หากคุณบังคับโหลดหน้าซ้ำ (shift-reload) ระบบจะข้าม Service Worker ทั้งหมด จะไม่มีการควบคุม ฟีเจอร์นี้อยู่ในข้อมูลจำเพาะ จึงใช้งานได้ในเบราว์เซอร์อื่นๆ ที่รองรับผู้ปฏิบัติงานใช้บริการ
การจัดการการอัปเดต
Service Worker ได้รับการออกแบบให้เป็นส่วนหนึ่งของ Extensible Web แนวคิดก็คือ เราในฐานะนักพัฒนาเบราว์เซอร์ ยอมรับว่าเราไม่ได้เก่งกว่านักพัฒนาเว็บ ด้วยเหตุนี้ เราจึงไม่ควรมอบ API ระดับสูงแบบแคบที่แก้ปัญหาบางอย่างโดยใช้รูปแบบที่เราชอบ แต่ให้คุณเข้าถึงเต็มรูปแบบของเบราว์เซอร์และให้คุณดำเนินการในแบบที่ต้องการด้วยวิธีที่เหมาะกับผู้ใช้ของคุณมากที่สุด
ดังนั้นในการทำให้รูปแบบมากที่สุดเท่าที่เราทำได้ วงจรการอัปเดตทั้งหมดจะสามารถสังเกตได้ นั่นคือ
navigator.serviceWorker.register('/sw.js').then(reg => {
reg.installing; // the installing worker, or undefined
reg.waiting; // the waiting worker, or undefined
reg.active; // the active worker, or undefined
reg.addEventListener('updatefound', () => {
// A wild service worker has appeared in reg.installing!
const newWorker = reg.installing;
newWorker.state;
// "installing" - the install event has fired, but not yet complete
// "installed" - install complete
// "activating" - the activate event has fired, but not yet complete
// "activated" - fully active
// "redundant" - discarded. Either failed install, or it's been
// replaced by a newer version
newWorker.addEventListener('statechange', () => {
// newWorker.state has changed
});
});
});
navigator.serviceWorker.addEventListener('controllerchange', () => {
// This fires when the service worker controlling this page
// changes, eg a new worker has skipped waiting and become
// the new active worker.
});
วงจรชีวิตต้องดำเนินต่อไป
คุณจะเห็นได้ว่า การทำความเข้าใจวงจรชีวิตของโปรแกรมทำงานของบริการนั้นมีประโยชน์ และการทำความเข้าใจนี้ทำให้พฤติกรรมของผู้ปฏิบัติงานบริการดูสมเหตุสมผลมากขึ้นและลึกลับน้อยลง ความรู้นี้จะช่วยให้คุณมั่นใจมากขึ้นเมื่อปรับใช้และอัปเดตโปรแกรมทำงานของบริการ