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

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

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

เจตนา

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

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

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

Service Worker รายแรก

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

  • เหตุการณ์ install เป็นเหตุการณ์แรกที่ Service Worker ได้รับ และจะเกิดขึ้นเพียงครั้งเดียว
  • สัญญาณบอกสถานะที่ส่งไปยัง installEvent.waitUntil() จะส่งสัญญาณแจ้งระยะเวลาและความสำเร็จหรือความล้มเหลวของการติดตั้งของคุณ
  • ผู้ให้บริการจะไม่รับเหตุการณ์อย่าง fetch และ push จนกว่าจะติดตั้งเสร็จสมบูรณ์และ "ทำงานอยู่"
  • โดยค่าเริ่มต้น การดึงข้อมูลของหน้าเว็บจะไม่ผ่าน Service Worker เว้นแต่คำขอหน้าเว็บจะผ่าน 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 หรือไม่ ซึ่งจะเป็นค่า Null หรืออินสแตนซ์ Service Worker

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

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

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

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

ติดตั้ง

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

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

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

เปิดใช้งาน

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

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

clients.claim

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

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

หากคุณใช้ 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) มีการอัปเดตหากมีไบต์ต่างจากที่เบราว์เซอร์มีอยู่แล้ว (เราจะขยายการดำเนินการนี้ให้ครอบคลุมสคริปต์/โมดูลที่นำเข้าด้วย)
  • ระบบจะเปิดใช้งาน Service Worker ที่อัปเดตแล้วควบคู่ไปกับ Service Worker ที่มีอยู่ และ Service Worker ดังกล่าวจะได้รับเหตุการณ์ install ของตนเอง
  • หากผู้ดําเนินการใหม่มีรหัสสถานะที่ไม่ถูกต้อง (เช่น 404) ไม่สามารถแยกวิเคราะห์ แสดงข้อผิดพลาดระหว่างการดําเนินการ หรือถูกปฏิเสธระหว่างการติดตั้ง ระบบจะทิ้งผู้ดําเนินการใหม่ แต่ผู้ดําเนินการปัจจุบันจะยังคงทํางานอยู่
  • เมื่อติดตั้งเรียบร้อยแล้ว แรงงานที่อัปเดตจะwaitจนกว่าแรงงานที่มีอยู่จะควบคุมไคลเอ็นต์เป็น 0 (โปรดทราบว่าไคลเอ็นต์จะทับซ้อนกันระหว่างการรีเฟรช)
  • 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 ใหม่รออยู่ในแท็บ "แอปพลิเคชัน" ของเครื่องมือสำหรับนักพัฒนาเว็บดังนี้

DevTools แสดง Service Worker ใหม่ที่กำลังรอ

แม้ว่าคุณจะเปิดแท็บเดโมไว้เพียงแท็บเดียว แต่การรีเฟรชหน้าเว็บก็ยังไม่เพียงพอที่จะทำให้เวอร์ชันใหม่ทำงานแทน ปัญหานี้เกิดจากวิธีการทำงานของการนําทางของเบราว์เซอร์ เมื่อคุณไปยังส่วนต่างๆ หน้าปัจจุบันจะไม่หายไปจนกว่าจะได้รับการตอบกลับที่มีส่วนหัว 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 ที่ไม่ซ้ำกันให้กับ 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 แล้ว การทำเช่นนี้เพื่อให้คุณสลับระหว่างเวอร์ชันต่างๆ ได้ในการแสดงตัวอย่าง ผมไม่ใช่สิ่งที่จะทำในเวอร์ชันที่ใช้งานจริง

การพัฒนาที่ง่ายดาย

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

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

รูปนี้ชอบที่สุด

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

ซึ่งจะเปลี่ยนวงจรให้นักพัฒนาแอปใช้งานได้ง่ายขึ้น การนําทางแต่ละรายการจะทําสิ่งต่อไปนี้

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

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

ไม่ต้องรอ

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

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

Shift-โหลดซ้ำ

หากคุณบังคับโหลดหน้าเว็บซ้ำ (กด Shift แล้วโหลดซ้ำ) ระบบจะข้าม Service Worker ทั้งหมด แต่จะควบคุมไม่ได้ ฟีเจอร์นี้อยู่ในข้อกำหนด จึงใช้งานได้ในเบราว์เซอร์อื่นๆ ที่รองรับ 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.
});

วงจรนี้ดำเนินต่อไปเรื่อยๆ

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