อัปเดต

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

คุณอัปเดตสิ่งต่อไปนี้ได้

  • ข้อมูลแอป
  • เนื้อหาที่แคชไว้ในอุปกรณ์แล้ว
  • ไฟล์ Service Worker หรือทรัพยากร Dependency
  • ข้อมูลเมตาของไฟล์ Manifest

เรามาดูแนวทางปฏิบัติแนะนำสำหรับองค์ประกอบแต่ละรายการเหล่านี้กัน

กำลังอัปเดตข้อมูล

หากต้องการอัปเดตข้อมูล เช่น ข้อมูลที่เก็บไว้ใน IndexedDB คุณสามารถใช้เครื่องมือ เช่น Fetch, WebRTC หรือ WebSockets API ได้ หากแอปสนับสนุนฟีเจอร์ออฟไลน์ทั้งหมด อย่าลืมอัปเดตข้อมูลที่รองรับให้อัปเดตอยู่เสมอด้วย

ในเบราว์เซอร์ที่เข้ากันได้ จะมีตัวเลือกให้ซิงค์ข้อมูลทั้งแบบเมื่อผู้ใช้เปิด PWA แล้วก็ทำงานในเบื้องหลังด้วย ตัวเลือกเหล่านี้ได้แก่:

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

กำลังอัปเดตเนื้อหา

การอัปเดตเนื้อหาประกอบด้วยการเปลี่ยนแปลงใดๆ ที่เกิดขึ้นกับไฟล์ที่คุณใช้แสดงผลอินเทอร์เฟซของแอป เช่น HTML, CSS, JavaScript และรูปภาพ ตัวอย่างเช่น การเปลี่ยนแปลงในตรรกะของแอป รูปภาพที่เป็นส่วนหนึ่งของอินเทอร์เฟซ หรือสไตล์ชีต CSS

อัปเดตรูปแบบ

ต่อไปนี้เป็นรูปแบบที่พบบ่อยในการจัดการการอัปเดตแอป แต่คุณสามารถปรับแต่งกระบวนการได้ตามต้องการ

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

กรณีที่ควรอัปเดต

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

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

ข้อมูลอัปเดตแบบเรียลไทม์

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

การอัปเดตเวอร์ชันที่ใช้จริงหมายถึงทันทีที่มีการอัปเดตเนื้อหาในแคช PWA จะแทนที่เนื้อหาในโหลดปัจจุบัน ซึ่งเป็นงานที่ซับซ้อนซึ่งไม่ได้ครอบคลุมในหลักสูตรนี้ เครื่องมือบางอย่างที่ช่วยในการติดตั้งการอัปเดตนี้ ได้แก่ livereload-js และ CSSStyleSheet.replace() API สำหรับการอัปเดตเนื้อหา CSS

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

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

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

กำลังตรวจหาการเปลี่ยนแปลง Service Worker

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

async function detectSWUpdate() {
  const registration = await navigator.serviceWorker.ready;

  registration.addEventListener("updatefound", event => {
    const newSW = registration.installing;
    newSW.addEventListener("statechange", event => {
      if (newSW.state == "installed") {
         // New service worker is installed, but waiting activation
      }
    });
  })
}

บังคับการลบล้าง

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

และแม้ว่าจะไม่แนะนำ แต่ Service Worker ใหม่ก็สามารถข้ามระยะเวลารอและเริ่มเปิดใช้งานได้ทันที

self.addEventListener("install", event => {
   // forces a service worker to activate immediately
   self.skipWaiting();
  });

self.addEventListener("activate", event => {
  // when this SW becomes activated, we claim all the opened clients
  // they can be standalone PWA windows or browser tabs
  event.waitUntil(clients.claim());
});

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

navigator.serviceWorker.addEventListener("controllerchange", event => {
   // The service worker controller has changed
 });

การอัปเดตข้อมูลเมตา

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

คำตอบขึ้นอยู่กับแพลตฟอร์ม มาดูตัวเลือกที่มีกัน

Safari ในเบราว์เซอร์ iOS, iPadOS และ Android

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

Google Chrome ใน Android ที่มี WebAPK

เมื่อผู้ใช้ติดตั้ง PWA ใน Android โดยใช้ Google Chrome พร้อมเปิดใช้งาน WebAPK (การติดตั้ง Chrome PWA ส่วนใหญ่) ระบบจะตรวจพบและใช้อัปเดตตามอัลกอริทึม ดูรายละเอียดได้ในบทความการอัปเดตไฟล์ Manifest นี้

หมายเหตุเพิ่มเติมเกี่ยวกับกระบวนการนี้

หากผู้ใช้ไม่ได้เปิด PWA ระบบจะไม่อัปเดต WebAPK หากเซิร์ฟเวอร์ไม่ตอบสนองด้วยไฟล์ Manifest (มีข้อผิดพลาด 404) Chrome จะไม่ตรวจหาการอัปเดตเป็นเวลาอย่างน้อย 30 วัน แม้ว่าผู้ใช้จะเปิด PWA ก็ตาม

ไปที่ about:webapks ใน Chrome บน Android เพื่อดูสถานะของ Flag "ต้องอัปเดต" และขอให้อัปเดต อ่านเพิ่มเติมเกี่ยวกับเครื่องมือแก้ไขข้อบกพร่องนี้ในบทเครื่องมือและการแก้ไขข้อบกพร่อง

Samsung Internet บน Android ที่มี WebAPK

กระบวนการนี้จะคล้ายกับเวอร์ชัน Chrome ในกรณีนี้ หากไฟล์ Manifest ของ PWA ต้องมีการอัปเดต ในช่วง 24 ชั่วโมงต่อจากนี้ WebAPK จะอัปเดตผ่าน Wi-Fi หลังจากสร้าง WebAPK ที่อัปเดตแล้ว

Google Chrome และ Microsoft Edge บนเดสก์ท็อป

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

เมื่อพร็อพเพอร์ตี้ที่เลือกได้รับการอัปเดตแล้ว ระบบจะทริกเกอร์การอัปเดตหลังจากปิดหน้าต่างทั้งหมดแล้ว

การแจ้งเตือนผู้ใช้

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

ใช้ตัวเลือกต่อไปนี้เพื่อแจ้งให้ผู้ใช้ทราบ

  • ใช้ DOM หรือ canvas API เพื่อแสดงผลการแจ้งเตือนบนหน้าจอ
  • ใช้ Web Notifications API API นี้เป็นส่วนหนึ่งของสิทธิ์พุชเพื่อสร้างการแจ้งเตือนในระบบปฏิบัติการ คุณจะต้องขอสิทธิ์การพุชจากเว็บเพื่อใช้งาน แม้ว่าจะไม่ได้ใช้โปรโตคอลการรับส่งข้อความพุชจากเซิร์ฟเวอร์ก็ตาม ตัวเลือกนี้เป็นตัวเลือกเดียวที่เรามีหากไม่ได้เปิด PWA
  • ใช้ Badging API เพื่อแสดงให้รู้ว่ามีการอัปเดตในไอคอนที่ติดตั้งของ PWA

การแจ้งเตือนการอัปเดตแสดงใน DOM.

ข้อมูลเพิ่มเติมเกี่ยวกับ Badging API

API ป้ายช่วยให้คุณทำเครื่องหมายไอคอนของ PWA ด้วยหมายเลขป้ายหรือจุดป้ายในเบราว์เซอร์ที่ใช้ร่วมกันได้ จุดป้ายเป็นเครื่องหมายเล็กๆ ภายในไอคอนที่ติดตั้งไว้ ซึ่งแสดงว่ามีบางสิ่งรออยู่ภายในแอป

ตัวอย่าง Twitter ที่มีการแจ้งเตือน 8 รายการและอีกแอปหนึ่งแสดงป้ายประเภทธง

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

let unreadCount = 125;
navigator.setAppBadge(unreadCount);

หากต้องการล้างป้าย ให้เรียกใช้ clearAppBadge() ในออบเจ็กต์เดียวกัน ดังนี้

navigator.clearAppBadge();

แหล่งข้อมูล