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

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

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

เจตนา

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

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

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

Service Worker รายการแรก

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

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

เราเรียกหน้าเว็บ ผู้ปฏิบัติงาน และผู้ปฏิบัติงานที่แชร์ว่า clients Service Worker จะควบคุมได้เฉพาะไคลเอ็นต์ที่อยู่ในขอบเขตเท่านั้น เมื่อ "ควบคุม" ไคลเอ็นต์แล้ว การดึงข้อมูลจะผ่าน Service Worker ที่อยู่ในขอบเขต คุณสามารถตรวจจับได้ว่าไคลเอ็นต์ควบคุมผ่าน navigator.serviceWorker.controller หรือไม่ ซึ่งจะเป็นค่า Null หรืออินสแตนซ์ Service Worker

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

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

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

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

ติดตั้ง

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

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

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

เปิดใช้งาน

เมื่อ 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 ที่มีอยู่ และ 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 และหน้าปัจจุบันอาจยังอยู่แม้ว่าจะมีการตอบกลับที่มีส่วนหัว Content-Disposition ก็ตาม การทำงานที่ซ้อนทับกันนี้ทำให้ Service Worker ปัจจุบันควบคุมไคลเอ็นต์อยู่เสมอระหว่างการรีเฟรช

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

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

เปิดใช้งาน

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

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

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

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

อันนี้เป็นภาพโปรด

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

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

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

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

ข้ามการรอ

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

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

Shift-โหลดซ้ำ

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