ข้ามไปยังเนื้อหา

Periodic Background Sync

Periodic Background Sync (PBS) ช่วยให้ PWA ที่ install แล้วปลุก service worker ให้ทำงานตามกำหนดเวลาซ้ำๆ เพื่อรีเฟรชข้อมูล — แม้เมื่อผู้ใช้ไม่ได้ใช้แอปอยู่ เมื่อผู้ใช้เปิดแอปครั้งต่อไป พวกเขาจะเห็นเนื้อหาใหม่แทนที่จะเป็นข้อมูลเก่า

คิดว่าเป็น cron job ที่ทำงานภายใน browser โดยขึ้นอยู่กับ heuristics ของ browser เองว่าเมื่อไหรที่ปลอดภัยและเป็นประโยชน์ที่จะปลุกแอปของคุณ

sequenceDiagram
  participant App as Installed PWA
  participant SW as Service Worker
  participant Browser as Browser Scheduler
  participant Net as Network / API

  App->>SW: registration.periodicSync.register('refresh-news', { minInterval })
  Browser-->>SW: periodicsync event (browser decides timing)
  SW->>Net: fetch('/api/latest-articles')
  Net-->>SW: JSON response
  SW->>SW: caches.open('news').put(...)
  Note over App: User opens app — sees fresh content
Periodic Background Sync flow
async function checkPeriodicSyncSupport() {
if (!('periodicSync' in (await navigator.serviceWorker.ready))) {
console.warn('Periodic Background Sync is not supported');
return false;
}
const status = await navigator.permissions.query({ name: 'periodic-background-sync' });
console.log('Periodic sync permission:', status.state); // "granted", "denied", or "prompt"
return status.state === 'granted';
}
async function registerPeriodicSync() {
const registration = await navigator.serviceWorker.ready;
if (!('periodicSync' in registration)) return;
try {
await registration.periodicSync.register('refresh-news', {
minInterval: 24 * 60 * 60 * 1000, // 24 hours in milliseconds
});
console.log('Periodic sync registered');
} catch (err) {
console.warn('Periodic sync registration failed:', err);
}
}

minInterval เป็นเพียง hint — browser จะ fire event ไม่บ่อยกว่า interval นี้ แต่อาจ fire น้อยกว่าหรือไม่ fire เลยขึ้นอยู่กับ heuristics ของตัวเอง

// sw.js — service worker
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'refresh-news') {
event.waitUntil(refreshNewsCache());
}
});
async function refreshNewsCache() {
const response = await fetch('/api/latest-articles');
if (!response.ok) return;
const cache = await caches.open('news-v1');
await cache.put('/api/latest-articles', response);
console.log('News cache refreshed at', new Date().toISOString());
}

event.waitUntil() ทำให้ SW ยังคงทำงานต่อจนกว่างาน async จะเสร็จสมบูรณ์ ถ้า fetch ของคุณใช้เวลานานเกินไปหรือล้มเหลว browser อาจไม่ retry ทันที

// List all registered periodic syncs
const registration = await navigator.serviceWorker.ready;
const tags = await registration.periodicSync.getTags();
console.log('Registered syncs:', tags);
// Unregister a specific sync
await registration.periodicSync.unregister('refresh-news');
ข้อจำกัดรายละเอียด
ต้อง install PWAPeriodic sync ต้องการให้แอปถูก install บน home screen หรือ desktop
เฉพาะ Chromiumณ ปี 2026 เฉพาะ browser ที่ใช้ Chromium เท่านั้นที่รองรับ PBS; Firefox และ Safari ไม่รองรับ
Browser กำหนด cadencebrowser ตัดสินใจ firing interval จริงตามแบตเตอรี่, เครือข่าย และ site engagement — ถือ minInterval เป็นค่าต่ำสุด ไม่ใช่ตาราง
ต้องมีเครือข่ายSW จะรัน handler เฉพาะเมื่ออุปกรณ์มีการเชื่อมต่อเครือข่าย
Engagement scoreChrome ติดตาม site engagement; เว็บไซต์ที่มี engagement ต่ำอาจมี PBS ถูก throttle หรือปิดใช้งาน
ต้องใช้ HTTPSเหมือนกับฟีเจอร์ service worker ทั้งหมด PBS ทำงานได้เฉพาะบน secure origins

เนื่องจาก browser ควบคุม cadence ออกแบบแอปให้ทำงานได้ถูกต้องแม้ periodicsync จะไม่ fire เลย:

  1. แสดงข้อมูลใน cache เสมอถ้า cache มีอยู่ — แม้ข้อมูลเก่าก็ดีกว่าหน้าจอว่างเปล่า
  2. รีเฟรชเมื่อเปิดหน้าเพจเป็น fallback เมื่อ periodic sync ไม่ได้ทำงาน
  3. แสดง timestamp “อัปเดตล่าสุด” เพื่อให้ผู้ใช้เข้าใจความสดของข้อมูล
// main.js — page code (fallback refresh on open)
async function loadArticles() {
const cache = await caches.open('news-v1');
const cached = await cache.match('/api/latest-articles');
if (cached) {
renderArticles(await cached.json());
// Still refresh in the background
fetch('/api/latest-articles').then(async (res) => {
if (res.ok) {
await cache.put('/api/latest-articles', res.clone());
renderArticles(await res.json());
}
});
} else {
const res = await fetch('/api/latest-articles');
const data = await res.json();
renderArticles(data);
}
}

บทเรียนแบบ code-only: Periodic Background Sync ต้องการ PWA ที่ install แล้วและมีเฉพาะใน browser ที่ใช้ Chromium ตัวอย่างด้านบนสมบูรณ์และถูกต้อง แต่ไม่สามารถรันใน in-browser playground ได้ ทดสอบใน Chrome หรือ Edge พร้อมกับ PWA ที่ install แล้ว

ตัวเลือกBenefitCost
Periodic Background Syncข้อมูลสดใหม่รอผู้ใช้อยู่แล้วตอนเปิดแอป โดยไม่ต้องรอโหลดต้องผ่านเกณฑ์ installed PWA + engagement heuristic ของ browser ก่อนถึงจะได้สิทธิ์ใช้
Sync ตอนเปิดแอปเท่านั้น (on-demand)ทำงานได้ทุก browser ไม่มีเงื่อนไขพิเศษผู้ใช้ต้องรอโหลดข้อมูลทุกครั้งที่เปิดแอป แม้เพิ่งเปิดไปเมื่อกี้
  • ตั้ง sync interval ถี่เกินไปโดยไม่สนใจว่า browser จะปรับ interval จริงตาม engagement ของผู้ใช้เองอยู่ดี (ตั้งเท่าไหร่ก็เป็นแค่ minimum)
  • ไม่ตรวจสิทธิ์ periodic-background-sync ก่อนเรียก register ทำให้โค้ด throw error บน browser ที่ยังไม่รองรับ
  • ใช้ periodic sync ดึงข้อมูลจำนวนมากโดยไม่สนใจ data usage ของผู้ใช้บนมือถือ ทำให้กิน quota โดยไม่รู้ตัว

แอปข่าวและแอปแผนที่ที่รีเฟรชเนื้อหาที่ cache ไว้ (หัวข้อข่าว, ข้อมูลจราจร) เป็นระยะเบื้องหลัง ให้พร้อมทันทีที่เปิดแอป คือ use case จริงทั่วไปของ API นี้ ไม่ว่าแอปนั้นจะใช้ Periodic Background Sync โดยตรงหรือกลไกอื่นก็ตาม

option minInterval ใน periodicSync.register() รับประกันอะไร?
ข้อใดจำเป็นสำหรับให้ Periodic Background Sync ทำงานได้?
event periodicsync ทำงานที่ไหน?
ทำไมจึงควรทำ fallback ที่ refresh ข้อมูลตอนโหลดหน้า?