Periodic Background Sync
Periodic Background Sync
หัวข้อที่มีชื่อว่า “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 การตรวจสอบ support และ permission
หัวข้อที่มีชื่อว่า “การตรวจสอบ support และ permission”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';}การ register periodic sync
หัวข้อที่มีชื่อว่า “การ register periodic sync”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 ของตัวเอง
การจัดการ periodicsync event ใน service worker
หัวข้อที่มีชื่อว่า “การจัดการ periodicsync event ใน service worker”// sw.js — service workerself.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 ทันที
การแสดงรายการและยกเลิก sync
หัวข้อที่มีชื่อว่า “การแสดงรายการและยกเลิก sync”// List all registered periodic syncsconst registration = await navigator.serviceWorker.ready;const tags = await registration.periodicSync.getTags();console.log('Registered syncs:', tags);
// Unregister a specific syncawait registration.periodicSync.unregister('refresh-news');ข้อจำกัดและความพร้อมใช้งาน
หัวข้อที่มีชื่อว่า “ข้อจำกัดและความพร้อมใช้งาน”| ข้อจำกัด | รายละเอียด |
|---|---|
| ต้อง install PWA | Periodic sync ต้องการให้แอปถูก install บน home screen หรือ desktop |
| เฉพาะ Chromium | ณ ปี 2025 เฉพาะ browser ที่ใช้ Chromium เท่านั้นที่รองรับ PBS; Firefox และ Safari ไม่รองรับ |
| Browser กำหนด cadence | browser ตัดสินใจ firing interval จริงตามแบตเตอรี่, เครือข่าย และ site engagement — ถือ minInterval เป็นค่าต่ำสุด ไม่ใช่ตาราง |
| ต้องมีเครือข่าย | SW จะรัน handler เฉพาะเมื่ออุปกรณ์มีการเชื่อมต่อเครือข่าย |
| Engagement score | Chrome ติดตาม site engagement; เว็บไซต์ที่มี engagement ต่ำอาจมี PBS ถูก throttle หรือปิดใช้งาน |
| ต้องใช้ HTTPS | เหมือนกับฟีเจอร์ service worker ทั้งหมด PBS ทำงานได้เฉพาะบน secure origins |
การออกแบบแบบ best-effort
หัวข้อที่มีชื่อว่า “การออกแบบแบบ best-effort”เนื่องจาก browser ควบคุม cadence ออกแบบแอปให้ทำงานได้ถูกต้องแม้ periodicsync จะไม่ fire เลย:
- แสดงข้อมูลใน cache เสมอถ้า cache มีอยู่ — แม้ข้อมูลเก่าก็ดีกว่าหน้าจอว่างเปล่า
- รีเฟรชเมื่อเปิดหน้าเพจเป็น fallback เมื่อ periodic sync ไม่ได้ทำงาน
- แสดง 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 แล้ว
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| 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 โดยไม่รู้ตัว
💡 ตัวอย่างจากของจริง
Google Maps — ใช้ periodic sync อัปเดตข้อมูลจราจร/แผนที่ที่เคย cache ไว้ให้สดใหม่อยู่เสมอแม้ไม่ได้เปิดแอป
แอปข่าวหลายเจ้า — sync หัวข้อข่าวล่าสุดเบื้องหลังเป็นระยะ ให้พร้อมอ่านทันทีที่เปิดแอปโดยไม่ต้องรอโหลด