วงจรการทำงานของโปรแกรมทำงานของบริการ

วงจรการทำงานของ Service Worker เป็นส่วนที่มีความซับซ้อนที่สุด หากคุณไม่ทราบว่าสิ่งนี้ใช้ทำอะไรและประโยชน์ที่ได้รับ อาจรู้สึกว่ากำลังต่อสู้อยู่กับคุณ แต่เมื่อคุณรู้วิธีการทำงานแล้ว คุณสามารถทำการอัปเดตที่ราบรื่นและไม่ก่อให้เกิดความรำคาญให้แก่ผู้ใช้ ด้วยการผสมผสานรูปแบบที่ดีที่สุดของเว็บกับรูปแบบเนทีฟเข้าด้วยกัน

เนื้อหานี้จะเจาะลึก แต่หัวข้อย่อยในตอนต้นของแต่ละส่วนจะครอบคลุมสิ่งที่คุณจำเป็นต้องทราบเกือบทั้งหมด

ความตั้งใจ

วัตถุประสงค์ของวงจรนี้คือ

  • ทำให้ออฟไลน์เป็นอันดับแรกได้
  • อนุญาตให้ Service Worker ใหม่เตรียมพร้อมตัวเองโดยไม่รบกวนการทำงานปัจจุบัน
  • ตรวจสอบว่าหน้าในขอบเขตได้รับการควบคุมโดย 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>

โปรแกรมนี้จะลงทะเบียนพนักงานบริการ และเพิ่มรูปภาพสุนัขหลังจากผ่านไป 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 หรือไม่ ซึ่งจะเป็น Null หรืออินสแตนซ์ Service Worker

ดาวน์โหลด แยกวิเคราะห์ และดำเนินการ

โปรแกรมทำงานของบริการคนแรกจะดาวน์โหลดเมื่อคุณโทรหา .register() หากสคริปต์ของคุณดาวน์โหลด แยกวิเคราะห์ หรือแสดงข้อผิดพลาดในการดำเนินการครั้งแรกไม่สำเร็จ สัญญาการลงทะเบียนจะถูกปฏิเสธ และ Service Worker จะถูกยกเลิก

เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome จะแสดงข้อผิดพลาดในคอนโซลและในส่วน Service Worker ของแท็บแอปพลิเคชัน ดังนี้

เกิดข้อผิดพลาดในแท็บเครื่องมือสำหรับนักพัฒนาเว็บของ Service Worker

ติดตั้ง

เหตุการณ์แรกที่ Service Worker ได้รับคือ install ระบบจะทริกเกอร์ทริกเกอร์ทันทีที่ผู้ปฏิบัติงานดำเนินการ และจะเรียกใช้เพียงครั้งเดียวต่อผู้ปฏิบัติงานด้านบริการ หากคุณแก้ไขสคริปต์ของ Service Worker เบราว์เซอร์จะถือว่าเป็นโปรแกรมทำงานอื่นและจะได้รับเหตุการณ์ install ของตัวเอง ฉันจะอธิบายรายละเอียดการอัปเดตในภายหลัง

เหตุการณ์ install เป็นโอกาสที่จะแคชทุกสิ่งที่คุณต้องการก่อนที่จะควบคุมไคลเอ็นต์ได้ คำมั่นสัญญาที่คุณส่งไปยัง event.waitUntil() จะช่วยให้เบราว์เซอร์ทราบว่าการติดตั้งของคุณเสร็จสมบูรณ์เมื่อใดและสำเร็จหรือไม่

หากคำสัญญาปฏิเสธ จะส่งผลให้การติดตั้งไม่สำเร็จและเบราว์เซอร์ทำให้โปรแกรมทำงานของบริการหายไป ควบคุมไคลเอ็นต์ไม่ได้ ซึ่งหมายความว่าเราพึ่งพา cat.svg ที่ปรากฏในแคชในเหตุการณ์ fetch ไม่ได้ เป็นการอ้างอิง

เปิดใช้งาน

เมื่อ Service Worker พร้อมที่จะควบคุมไคลเอ็นต์และจัดการกิจกรรมที่ใช้งานได้ เช่น push และ sync คุณจะได้รับเหตุการณ์ activate แต่นั่นไม่ได้หมายความว่าจะมีการควบคุมหน้าที่ชื่อ .register()

ครั้งแรกที่คุณโหลดเดโม แม้ว่าจะมีการขอ dog.svg ไว้นานหลังจากที่โปรแกรมทำงานของบริการเปิดใช้งาน แต่โปรแกรมทำงานก็ไม่ได้จัดการคำขอ และคุณจะยังคงเห็นรูปภาพสุนัข ค่าเริ่มต้นคือความสม่ำเสมอ หากหน้าเว็บของคุณโหลดโดยไม่มี Service Worker ทรัพยากรย่อยของหน้านั้นก็จะไม่โหลดเช่นกัน หากคุณโหลดเดโมเป็นครั้งที่ 2 (กล่าวคือ ให้รีเฟรชหน้าเว็บ) รายการดังกล่าวก็จะถูกควบคุม ทั้งหน้าเว็บและรูปภาพจะเข้าสู่เหตุการณ์ fetch รายการ และคุณจะเห็นแมวแทน

clients.claim

คุณควบคุมไคลเอ็นต์ที่ไม่มีการควบคุมได้โดยโทรหา clients.claim() ภายใน Service Worker เมื่อเปิดใช้งานแล้ว

นี่คือรูปแบบของเดโมด้านบนซึ่งเรียกใช้ clients.claim() ในเหตุการณ์ activate คุณควรเห็นแมวในครั้งแรก ฉันพูดว่า "ควร" เพราะข้อมูลนี้คำนึงถึงเวลา คุณจะเห็นแมวก็ต่อเมื่อ Service Worker เปิดใช้งานและ clients.claim() มีผลก่อนที่รูปภาพจะพยายามโหลด

กรณีที่ใช้ Service Worker เพื่อโหลดหน้าเว็บซึ่งต่างจากการโหลดผ่านเครือข่าย clients.claim() อาจสร้างปัญหาได้เนื่องจากโปรแกรมทำงานของบริการควบคุมไคลเอ็นต์บางอย่างที่โหลดโดยไม่มีโปรแกรมทำงานนั้น

กำลังอัปเดต Service Worker

เคล็ดลับโดยสรุปมีดังนี้

  • ระบบจะทริกเกอร์การอัปเดตหากเกิดเหตุการณ์ต่อไปนี้
    • การนำทางไปยังหน้าในขอบเขต
    • เหตุการณ์ที่ใช้งานได้ เช่น push และ sync เว้นแต่จะมีการตรวจสอบการอัปเดตภายใน 24 ชั่วโมงที่ผ่านมา
    • กำลังโทรหา .register() เฉพาะเมื่อ URL ของ Service Worker มีการเปลี่ยนแปลง แต่ควรหลีกเลี่ยงการเปลี่ยน URL ของผู้ปฏิบัติงาน
  • เบราว์เซอร์ส่วนใหญ่ ซึ่งรวมถึง Chrome 68 ขึ้นไป จะละเว้นส่วนหัวการแคชเป็นค่าเริ่มต้นเมื่อตรวจหาการอัปเดตสคริปต์ Service Worker ที่ลงทะเบียนไว้ ทั้งนี้ ระบบยังคงใช้ส่วนหัวการแคชเมื่อดึงข้อมูลทรัพยากรที่โหลดภายใน Service Worker ผ่าน importScripts() คุณลบล้างลักษณะการทำงานเริ่มต้นนี้ได้โดยตั้งค่าตัวเลือก updateViaCache เมื่อลงทะเบียน Service Worker
  • เราจะถือว่าโปรแกรมทำงานของบริการมีการอัปเดตหากข้อมูลนั้นแตกต่างจากที่เบราว์เซอร์มีอยู่แล้ว (เรากำลังขยายเรื่องนี้ให้ครอบคลุมสคริปต์/โมดูลที่นำเข้าด้วย)
  • จะมีการเปิดตัว Service Worker ที่อัปเดตไปพร้อมกับโปรแกรมที่มีอยู่ และรับเหตุการณ์ install ของตัวเอง
  • หากผู้ปฏิบัติงานใหม่มีรหัสสถานะที่ไม่ปกติ (เช่น 404) แยกวิเคราะห์ไม่สำเร็จ แสดงข้อผิดพลาดระหว่างปฏิบัติการ หรือปฏิเสธระหว่างการติดตั้ง ผู้ปฏิบัติงานใหม่จะหายไป แต่ผู้ปฏิบัติงานปัจจุบันยังคงทำงานอยู่
  • เมื่อติดตั้งเสร็จเรียบร้อยแล้ว ผู้ปฏิบัติงานที่อัปเดตจะwait จนกว่าผู้ปฏิบัติงานที่มีอยู่จะควบคุมเครื่องไคลเอ็นต์ (โปรดทราบว่าไคลเอ็นต์ทับซ้อนกันระหว่างการรีเฟรช)
  • self.skipWaiting() จะป้องกันไม่ให้ต้องรอ ซึ่งหมายความว่า Service Worker จะเปิดใช้งานทันทีที่ติดตั้งเสร็จ

สมมติว่าเราเปลี่ยนสคริปต์ของ Service Worker ให้ตอบกลับด้วยภาพม้าแทนแมว ดังนี้

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

กำลังรอ

หลังจากติดตั้งเรียบร้อยแล้ว โปรแกรมทำงานของบริการที่อัปเดตจะหน่วงเวลาการเปิดใช้งานจนกว่าโปรแกรมทำงานของบริการที่มีอยู่จะไม่ควบคุมไคลเอ็นต์อีกต่อไป สถานะนี้เรียกว่า "กำลังรอ" และเป็นเหตุผลที่เบราว์เซอร์ทำให้มั่นใจได้ว่ามี Service Worker เพียงเวอร์ชันเดียวเท่านั้นที่กำลังทำงาน

หากคุณใช้งานการสาธิตที่อัปเดตแล้ว คุณควรจะยังเห็นรูปแมวอยู่ เนื่องจากยังไม่ได้เปิดใช้งานผู้ปฏิบัติงาน V2 คุณจะเห็น Service Worker ใหม่รออยู่ในแท็บ "แอปพลิเคชัน" ของเครื่องมือสำหรับนักพัฒนาเว็บ โดยทำดังนี้

เครื่องมือสำหรับนักพัฒนาเว็บแสดง Service Worker ใหม่กำลังรอ

แม้ว่าคุณจะเปิดแท็บเดโมไว้เพียงแท็บเดียว แต่การรีเฟรชหน้าเว็บยังไม่พอที่จะทำให้เวอร์ชันใหม่เริ่มทำงานได้ ปัญหานี้เกิดจากการไปยังส่วนต่างๆ ของเบราว์เซอร์ เมื่อคุณไปยังส่วนต่างๆ หน้าปัจจุบันจะไม่หายไปจนกว่าจะได้รับส่วนหัวของการตอบกลับ และแม้ว่าหน้าปัจจุบันอาจยังอยู่ต่อไปหากการตอบกลับมีส่วนหัว Content-Disposition เนื่องจากการซ้อนทับนี้ โปรแกรมทำงานของบริการในปัจจุบันจึงควบคุมไคลเอ็นต์เสมอในระหว่างการรีเฟรช

หากต้องการรับการอัปเดต ให้ปิดหรือออกจากแท็บทั้งหมดโดยใช้ Service Worker ปัจจุบัน จากนั้น เมื่อไปที่เดโมอีกครั้ง คุณควรเห็นม้า

รูปแบบนี้คล้ายกับการอัปเดตของ Chrome การอัปเดต Chrome จะดาวน์โหลดในเบื้องหลัง แต่จะไม่มีผลจนกว่า Chrome จะรีสตาร์ท ในระหว่างนี้ คุณจะยังใช้เวอร์ชันปัจจุบันต่อไปได้โดยไม่มีการหยุดชะงัก อย่างไรก็ตาม ขั้นตอนนี้เป็นเรื่องยุ่งยากในระหว่างการพัฒนา แต่เครื่องมือสำหรับนักพัฒนาเว็บยังมีวิธีทำให้ง่ายขึ้น ซึ่งฉันจะพูดถึงในบทความนี้

เปิดใช้งาน

การดำเนินการนี้จะเริ่มทำงานเมื่อ Service Worker เดิมหายไป และ Service Worker ใหม่จะควบคุมไคลเอ็นต์ได้ นี่เป็นช่วงเวลาที่เหมาะจะทำสิ่งที่คุณทำไม่ได้ในขณะที่พนักงานเก่ายังใช้งานอยู่ เช่น การย้ายฐานข้อมูลและการล้างแคช

ในการสาธิตด้านบน ฉันเก็บรักษารายการแคชที่ฉันคาดว่าจะมีอยู่ และในเหตุการณ์ activate ฉันจะลบทิ้งอื่นๆ ซึ่งจะนำแคชเก่าของ static-v1 ออก

หากคุณส่งคำสัญญาไปยัง event.waitUntil() ก็จะบัฟเฟอร์เหตุการณ์ที่ใช้งานได้ (fetch, push, sync ฯลฯ) จนกว่าสัญญาจะได้รับการแก้ไข ดังนั้นเมื่อเหตุการณ์ fetch เริ่มทำงาน การเปิดใช้งานจึงจะสมบูรณ์

ข้ามขั้นตอนการรอ

ระยะรอหมายความว่าคุณใช้งานเว็บไซต์เพียงเวอร์ชันเดียวพร้อมกัน แต่หากไม่ต้องการใช้ฟีเจอร์ดังกล่าว คุณทำให้ Service Worker ใหม่เปิดใช้งานได้เร็วขึ้นโดยโทรหา self.skipWaiting()

การดำเนินการนี้จะทำให้ Service Worker ไล่ผู้ปฏิบัติงานที่ใช้งานอยู่ในปัจจุบันออก และเปิดใช้งานตัวเองทันทีที่เข้าสู่ระยะการรอ (หรือทันทีหากอยู่ในระยะการรอแล้ว) โดยไม่ต้องรอการติดตั้ง แต่ไม่ทำให้ผู้ปฏิบัติงานของคุณข้ามการติดตั้งได้

ไม่สำคัญว่าคุณจะโทรหา skipWaiting() ตราบใดที่ยังอยู่ในระหว่างหรือรอก่อน เป็นเรื่องปกติที่จะมีการเรียกในเหตุการณ์ install:

self.addEventListener('install', event => {
  self.skipWaiting();

  event.waitUntil(
    // caching etc
  );
});

แต่คุณอาจต้องเรียกว่าเป็นผลลัพธ์ของ postMessage() สำหรับ Service Worker เช่นเดียวกับ คุณต้องการskipWaiting()ติดตามการโต้ตอบของผู้ใช้

นี่คือการสาธิตที่ใช้ skipWaiting() คุณจะเห็นภาพวัวโดยไม่ต้องนำทางออกไป clients.claim() เหมือนกับการแข่งขัน ดังนั้นคุณจะเห็นวัวก็ต่อเมื่อโปรแกรมทำงานของบริการใหม่ดึง ติดตั้ง และเปิดใช้งานก่อนที่หน้าเว็บจะพยายามโหลดรูปภาพ

อัปเดตด้วยตนเอง

อย่างที่ได้กล่าวไปแล้วก่อนหน้านี้ เบราว์เซอร์จะตรวจหาการอัปเดตโดยอัตโนมัติหลังจากการนำทางและเหตุการณ์ฟังก์ชันการทำงาน แต่คุณสามารถทริกเกอร์การอัปเดตด้วยตนเองได้โดยทำดังนี้

navigator.serviceWorker.register('/sw.js').then(reg => {
  // sometime later…
  reg.update();
});

หากคาดว่าผู้ใช้จะใช้เว็บไซต์เป็นเวลานานโดยไม่ต้องโหลดซ้ำ คุณอาจต้องโทรหา update() เป็นช่วงๆ (เช่น ทุกชั่วโมง)

หลีกเลี่ยงการเปลี่ยน URL ของสคริปต์โปรแกรมทำงานของบริการ

ถ้าคุณได้อ่านโพสต์ของฉันเกี่ยวกับแนวทางปฏิบัติแนะนำในการแคชแล้ว คุณอาจลองกำหนด URL ที่ไม่ซ้ำกันให้กับ Service Worker แต่ละเวอร์ชัน อย่าทำเช่นนี้ ซึ่งมักจะเป็นแนวทางปฏิบัติที่ไม่ดีสำหรับ Service Worker เพียงแต่อัปเดตสคริปต์ที่ตำแหน่งปัจจุบันของสคริปต์เท่านั้น

อาจทำให้คุณมีปัญหาดังนี้:

  1. index.html ลงทะเบียน sw-v1.js เป็น Service Worker
  2. sw-v1.js แคชและแสดง index.html เพื่อให้ทำงานแบบออฟไลน์ก่อน
  3. คุณอัปเดต index.html เพื่อให้ลงทะเบียน sw-v2.js เครื่องใหม่ของคุณ

หากคุณดำเนินการข้างต้น ผู้ใช้จะไม่ได้รับ sw-v2.js เพราะ sw-v1.js กำลังแสดง index.html เวอร์ชันเก่าจากแคช คุณได้เลื่อนตำแหน่งเป็นจุดที่ต้องอัปเดต Service Worker เพื่ออัปเดต Service Worker แล้ว อ้าว

แต่สำหรับการสาธิตด้านบน เราได้เปลี่ยน URL ของ Service Worker แล้ว สำหรับการสาธิต คุณสามารถสลับระหว่างรุ่นได้ ฉันไม่ได้ทำในการผลิตคอนเทนต์เลย

ทำให้การพัฒนาเป็นเรื่องง่าย

วงจรการทำงานของ Service Worker นั้นสร้างขึ้นโดยคำนึงถึงผู้ใช้เป็นหลัก แต่ในระหว่างการพัฒนาก็จะมีขั้นตอนที่ยุ่งยากเล็กน้อย โชคดีที่มีเครื่องมือ 2-3 อย่างที่จะช่วยคุณได้

อัปเดตเมื่อโหลดซ้ำ

รูปนี้โปรดเลย

เครื่องมือสำหรับนักพัฒนาเว็บแสดง &quot;อัปเดตเมื่อโหลดซ้ำ&quot;

ซึ่งจะเปลี่ยนวงจรให้เป็นมิตรกับนักพัฒนาซอฟต์แวร์ การนำทางแต่ละครั้งจะทำงานดังนี้

  1. ดึงข้อมูล Service Worker อีกครั้ง
  2. ติดตั้งเป็นเวอร์ชันใหม่แม้ว่าจะเป็นเวอร์ชันที่เหมือนกันทุกประการแบบไบต์ จากนั้นเหตุการณ์ install จะทำงานและการอัปเดตแคช
  3. ข้ามขั้นตอนการรอเพื่อให้ Service Worker ใหม่เปิดใช้งาน
  4. ไปยังส่วนต่างๆ ของหน้า

ซึ่งหมายความว่าคุณจะได้รับการอัปเดตในการนำทางแต่ละครั้ง (รวมถึงการรีเฟรช) โดยไม่ต้องโหลดซ้ำ 2 ครั้งหรือปิดแท็บ

ไม่ต้องรอ

เครื่องมือสำหรับนักพัฒนาเว็บแสดง &quot;การข้ามกำลังรอ&quot;

หากคุณมีพนักงานที่รออยู่ คุณสามารถกด "ข้ามการรอ" ในเครื่องมือสำหรับนักพัฒนาเว็บเพื่อเลื่อนสถานะเป็น "ใช้งานอยู่" ทันที

Shift โหลดซ้ำ

การบังคับให้โหลดหน้าซ้ำ (Shift-reload) จะเป็นการข้าม Service Worker โดยสิ้นเชิง จะไม่มีการควบคุม ฟีเจอร์นี้อยู่ในข้อมูลจำเพาะ ดังนั้นจึงใช้ได้ในเบราว์เซอร์อื่นๆ ที่รองรับโปรแกรมทำงานของบริการ

การจัดการการอัปเดต

Service Worker ออกแบบมาเป็นส่วนหนึ่งของเว็บที่ขยายได้ แนวคิดก็คือ เราในฐานะนักพัฒนาเบราว์เซอร์ รับทราบว่าเราไม่ได้มีการพัฒนาเว็บได้ดีกว่านักพัฒนาเว็บ ด้วยเหตุนี้ เราจึงไม่ควรให้บริการ 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.
});

วงจรการใช้งานเป็นไปอย่างไม่มีที่สิ้นสุด

ดังที่คุณได้เห็น การทำความเข้าใจวงจรการทำงานของโปรแกรมทำงานของบริการจึงคุ้มค่า และด้วยความเข้าใจนี้ พฤติกรรมของผู้ปฏิบัติงานบริการควรดูสมเหตุสมผลมากกว่าและลึกลับน้อยลง ความรู้ดังกล่าวจะช่วยให้คุณมีความมั่นใจมากขึ้นเมื่อติดตั้งใช้งานและอัปเดต Service Worker