การใช้หน้าต่างกล่องงาน

โมดูล Workbox จำนวน 1 รายการที่ยังไม่ครอบคลุมมากนักในเอกสารนี้คือ workbox-window ซึ่งเป็นชุดโมดูลที่ตั้งใจจะใช้งานใน window วัตถุประสงค์ของโมดูลนี้ได้แก่

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

การนำเข้าและการใช้ workbox-window

การส่งออกที่คุณใช้บ่อยที่สุดจาก workbox-window คือคลาส Workbox ซึ่งคุณสามารถนำเข้าในโหนดหรือจาก CDN ในหน้าเว็บได้

การสร้างแพ็กเกจในเครื่อง

หาก Toolchain มี Bundler เช่น webpack หรือ Rollup คุณจะรวม workbox-window ในเครื่องได้

ขั้นแรก ให้ติดตั้ง workbox-window เป็นทรัพยากร Dependency ของแอปพลิเคชันจริงดังนี้

npm install workbox-window --save

จากนั้นใน JavaScript ของแอปพลิเคชัน คุณจะimportคลาส Workbox ได้จาก workbox-window ดังนี้

<script type="module">
import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}
</script>

แม้ว่า workbox-window จะมีขนาดค่อนข้างเล็ก แต่คุณก็สามารถแยกค่าออกจากตรรกะแอปพลิเคชันหลักของเว็บไซต์โดยใช้ฟีเจอร์importแบบไดนามิก ซึ่งจะลดขนาดกลุ่มหลักของหน้าได้ ดังนี้

<script type="module">
if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}
</script>

การใช้ CDN

แม้จะไม่ใช่วิธีการที่แนะนำ แต่วิธีใช้ workbox-window ที่ง่ายกว่าคือการนำเข้าจาก CDN วิธีการมีดังนี้

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

โปรดทราบว่าองค์ประกอบ <script> ในตัวอย่างด้านบนใช้แอตทริบิวต์ type="module" คุณจำเป็นต้องดำเนินการนี้หากต้องการใช้คำสั่ง import แบบคงที่ในเบราว์เซอร์โดยไม่มีขั้นตอนการสร้าง เบราว์เซอร์หลักๆ ทั้งหมดที่รองรับโปรแกรมทำงานของบริการรองรับโมดูล JavaScript ด้วย ดังนั้น แสดงโค้ดนี้ในเบราว์เซอร์ใดก็ได้ เนื่องจากเบราว์เซอร์รุ่นเก่าจะไม่สนใจองค์ประกอบ <script> ที่มีค่าแอตทริบิวต์ type เป็น "module"

การลงทะเบียน Service Worker

การลงทะเบียน Service Worker ด้วย workbox-window จะดำเนินการโดยใช้เมธอด register ของคลาส Workbox ดังนี้

import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

ดูเหมือนว่านี่จะเหมือนกับการลงทะเบียนโปรแกรมทำงานของบริการด้วยตัวคุณเองโดยใช้ navigator.serviceWorker.register แต่ Workbox.register จะรอจนกว่าเหตุการณ์ window load จึงจะลงทะเบียน Service Worker ได้ วิธีนี้เหมาะสำหรับกรณีที่ต้องมีการแคชล่วงหน้า ดังนั้นการช่วงชิงแบนด์วิดท์อาจทำให้การเริ่มต้นหน้าเว็บล่าช้าได้

การสื่อสารระหว่าง window กับขอบเขตของ Service Worker

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

โดย Workbox จะใช้รูปแบบที่เฉพาะเจาะจงสำหรับข้อความ โดยเป็นออบเจ็กต์ที่มีพร็อพเพอร์ตี้ดังต่อไปนี้

  • type คือสตริงที่ไม่ซ้ำกันซึ่งต้องระบุเพื่อระบุข้อความ รูปแบบควรเป็นตัวพิมพ์ใหญ่ และมีขีดล่างที่แยกคำ (เช่น CACHE_URLS)
  • meta เป็นสตริงที่ไม่บังคับซึ่งแสดงชื่อของแพ็กเกจ Workbox ที่ส่งข้อความ และโดยปกติจะละเว้นไว้
  • payload เป็นพารามิเตอร์ที่ไม่บังคับซึ่งแสดงข้อมูลที่คุณต้องการส่ง ซึ่งอาจเป็นข้อมูลประเภทใดก็ได้

ด้านล่างนี้เป็นตัวอย่างวิธีการทำงานของ messageSW โดยเริ่มต้นด้วยโค้ดใน Service Worker ของคุณ ดังนี้

// sw.js
const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

ตามด้วยโค้ดต่อไปนี้ในหน้าเว็บของคุณ

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

มีหลายกรณีที่การสื่อสารระหว่าง Service Worker กับ window ก็มีประโยชน์ เช่น การแจ้งผู้ใช้เมื่อมีอัปเดตโปรแกรมทำงานของบริการ สูตรดังกล่าวอาศัยวิธีการผู้ช่วยพิเศษสําหรับ self.skipWaiting ที่ชื่อ messageSkipWaiting ซึ่งส่งข้อความที่มีค่า type เป็น SKIP_WAITING