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

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

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

ความตั้งใจ

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

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

ติดตั้ง

เหตุการณ์แรกที่ 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 ใหม่กำลังรอดำเนินการ

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

ซึ่งอาจนำคุณไปสู่ปัญหาดังนี้

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

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

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

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

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

อันนี้ชอบสุดเลย

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

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

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

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

ไม่ต้องรอ

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

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

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.
});

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

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