Category: guide
Service Workers — Cache Strategy สำหรับ Static Site
คู่มือ Service Worker สำหรับ offline caching, stale-while-revalidate และ cache management บน static site
สารบัญ
Service Worker คืออะไร
Service Worker เป็น JavaScript ที่รันใน background thread แยกจาก page — intercept network requests และ serve จาก cache ได้ ทำให้ site ทำงาน offline และโหลดเร็วขึ้นมาก
Register
// main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
Cache Strategies
Cache First (static assets)
// sw.js
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cached) =>
cached ?? fetch(event.request).then((res) => {
const clone = res.clone();
caches.open('v1').then((cache) => cache.put(event.request, clone));
return res;
})
)
);
});
Stale-While-Revalidate (HTML pages)
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.open('pages').then(async (cache) => {
const cached = await cache.match(event.request);
const fetchPromise = fetch(event.request).then((res) => {
cache.put(event.request, res.clone());
return res;
});
return cached ?? fetchPromise;
})
);
});
Install & Activate
const CACHE_NAME = 'site-v2';
const PRECACHE = ['/', '/offline.html', '/styles.css'];
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(CACHE_NAME).then((c) => c.addAll(PRECACHE)));
self.skipWaiting();
});
self.addEventListener('activate', (e) => {
e.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k)))
)
);
self.clients.claim();
});
Workbox — ทำให้ง่ายขึ้นมาก
npm install workbox-window
// sw.js (generated by Workbox CLI)
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';
precacheAndRoute(self.__WB_MANIFEST); // inject during build
registerRoute(
({ request }) => request.destination === 'document',
new StaleWhileRevalidate({ cacheName: 'pages' })
);