Common Front-End Caching Techniques and Service Worker Guide
The article explains common front‑end caching methods—including HTTP headers, browser storage, and HTML5 manifests—then provides a comprehensive guide to Service Workers, covering their lifecycle, registration, typical install/activate/fetch handlers, cache‑update strategies, background sync, and integration with Taro via Workbox.
Front-End Common Caching Techniques
Front‑end caching is generally divided into HTTP caching and browser caching.
HTTP Cache
Expires – HTTP/1.0 header that tells the client the response is fresh until a specific date.
Cache‑Control – HTTP/1.1 header that uses max-age to specify how long a resource may be cached, solving the fixed‑time problem of Expires .
Last‑Modified / If‑Modified‑Since – The server sends the last modification time; the client sends it back in the request. If the server’s Last‑Modified is newer, it returns 200 , otherwise 304 .
ETag / If‑None‑Match – The server generates a unique identifier for each version of a resource. If the client’s If‑None‑Match matches the current ETag, the server returns 304 , otherwise 200 with the new content.
Browser Cache
Storage – cookie, localStorage , sessionStorage (built‑in browser storage).
Manifest – HTML5 offline cache manifest for static files.
Service Worker – A script that runs in the background, intercepts network requests, provides offline experiences, and enables push notifications and background sync.
Service Worker Introduction
Service Worker acts as a proxy between the web application and the network. It runs on HTTPS (or localhost for development) and cannot access the DOM directly, but can communicate with the main thread via postMessage .
Service Worker Features
Runs in a separate thread, does not block the main JavaScript thread.
Requires HTTPS for security.
Has an independent lifecycle unrelated to page lifetimes.
Service Worker Lifecycle
Parsed – The script is parsed and the registration object becomes available.
Installing – The install event fires; developers usually cache assets here.
Installed / Waiting – The worker is installed but not yet controlling pages.
Activating – The activate event fires; old caches are typically cleared.
Activated – The worker controls pages and can handle fetch and message events.
Redundant – The worker becomes redundant if installation or activation fails, or a newer worker replaces it.
Example of registration:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(function (registration) {
console.log("Service Worker Registered", registration);
})
.catch(function (err) {
console.log("Service Worker Failed to Register", err);
});
}Typical install handler:
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(currentCacheName).then(function (cache) {
return cache.addAll(arrayOfFilesToCache);
})
);
});Typical activate handler (clears old caches):
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames.filter(function (cacheName) {
return cacheName != currentCacheName;
}).map(function (cacheName) {
return caches.delete(cacheName);
})
);
})
);
});Typical fetch handler (cache‑first strategy):
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
return response || fetch(event.request);
})
);
});Cache Update Example
const version = '2.0';
const currentCache = 'my-cache' + version;
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames.map(function (cacheName) {
if (cacheName !== currentCache) {
return caches.delete(cacheName);
}
})
);
})
);
});Unregistering a Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}Cache Strategies
Cache only – Serve only from the cache.
Network only – Bypass the cache, always fetch from the network.
Cache first – Try cache, fall back to network and then cache the result.
Network first – Try network, fall back to cache if offline.
Stale‑while‑revalidate – Return cached response immediately, then update the cache in the background.
Background Sync
When a page triggers a sync event, the Service Worker can perform network requests later, ensuring data is sent even after the user goes offline.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js');
navigator.serviceWorker.ready.then(function (registration) {
let tag = "data_sync";
document.getElementById('submit-btn').addEventListener('click', function () {
registration.sync.register(tag).then(function () {
console.log('Background sync triggered', tag);
}).catch(function (err) {
console.log('Background sync failed', err);
});
});
});
}Service Worker listener for the sync event:
self.addEventListener('sync', function (e) {
let init = { method: 'GET' };
switch (e.tag) {
case "data_sync":
let request = new Request(`xxxxx/sync`, init);
e.waitUntil(fetch(request).then(function (response) {
return response;
}));
break;
}
});Integration with Taro (using workbox‑webpack‑plugin)
Configuration in the Taro config file:
const { GenerateSW } = require('workbox-webpack-plugin');
const config = {
...,
h5: {
...,
webpackChain(chain) {
...
chain.plugin('generateSW').use(new GenerateSW({
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [{
urlPattern: /.*\/,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'my-webcache',
expiration: { maxEntries: 2000 }
}
}]
}));
}
}
};Registering the generated Service Worker in the project:
import { register } from 'register-service-worker';
register('./service-worker.js', {
registrationOptions: { scope: './' },
ready(registration) { console.log('Service worker is active.', registration); },
registered(registration) { console.log('Service worker has been registered.', registration); },
cached(registration) { console.log('Content has been cached for offline use.', registration); },
updatefound(registration) { console.log('New content is downloading.', registration); },
updated(registration) { console.log('New content is available; please refresh.', registration); },
offline() { console.log('No internet connection found. App is running in offline mode.'); },
error(error) { console.error('Error during service worker registration:', error); }
});After building, the plugin generates a Service Worker file. When the app is run, the first request is cached, and subsequent offline navigation serves the cached assets.
Overall, Service Workers provide powerful capabilities beyond offline caching, such as push notifications, background sync, and inter‑page communication.
HelloTech
Official Hello technology account, sharing tech insights and developments.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.