Overview
The Mini POS System implements a service worker (sw.js) that provides offline-first functionality through intelligent caching. The service worker enables the application to:
- Work offline after the first visit
- Load instantly from cache
- Update automatically when new versions are deployed
- Fallback gracefully when network requests fail
Cache Versioning
The cache version is controlled by theCACHE constant:
- Increment the version number (e.g.,
mini-pos-v3) - Deploy the updated
sw.jsfile - The service worker will automatically clear old caches on activation
Cached Assets
TheASSETS array defines all files cached during installation:
CDN resources are intentionally excluded from the cache due to CORS restrictions. All required CSS is bundled locally in
css/style.css.Service Worker Lifecycle
Install Event
The install event caches all application assets when the service worker is first installed or updated:- Uses
Promise.allSettled()to handle individual asset failures gracefully - Calls
self.skipWaiting()to activate immediately without waiting for old tabs to close - Does not fail installation if some assets can’t be cached
Activate Event
The activate event cleans up old caches when a new service worker version takes control:- Deletes all caches except the current version
- Calls
self.clients.claim()to take control of all open tabs immediately - Ensures users always have the latest cached assets
Fetch Event
The fetch event implements a cache-first strategy with network fallback:- Only intercepts GET requests - POST, PUT, DELETE requests bypass the service worker
- Check cache first - If resource is cached, return it immediately
- Network fallback - If not cached, fetch from network
- Cache on success - Clone and cache successful network responses
- Offline fallback - If network fails, serve
index.htmlas fallback
Caching Strategy
Cache-First Approach
The service worker implements a cache-first strategy:- Cached resources load instantly without network requests
- Perfect for offline functionality
- New content requires cache version bump
Dynamic Caching
Resources not in theASSETS array are cached dynamically:
- First request fetches from network and caches response
- Subsequent requests serve from cache
- Applies to images, API responses, and other GET requests
Offline Fallback
When both cache and network fail, the service worker servesindex.html. This ensures:
- Users always see something instead of browser error pages
- The application shell loads even when specific resources fail
- Navigation remains functional offline
CORS Handling
Solution implemented:- All CSS is bundled locally in
css/style.css - No external CDN dependencies in the
ASSETSarray - Individual cache failures are silently ignored during installation
Updating the Service Worker
Manual Cache Clear
To force update the cache version:-
Edit
sw.jsand increment the version: - Deploy the updated file
-
The service worker will:
- Install the new version
- Activate and delete old caches
- Cache all assets with the new version name
Testing Updates
Browsers check for service worker updates:- On navigation to a page in scope
- Every 24 hours (browser-dependent)
- When
navigator.serviceWorker.register()is called
Debugging Tips
Chrome DevTools
-
View registered service workers:
- Navigate to
chrome://serviceworker-internals/ - Or open DevTools → Application → Service Workers
- Navigate to
-
Clear cache:
- DevTools → Application → Storage → Clear site data
- Or Application → Cache Storage → Delete caches manually
-
Test offline:
- DevTools → Network → Check “Offline”
- Or Application → Service Workers → “Offline” checkbox
-
Force update:
- Application → Service Workers → Click “Update”
- Or check “Update on reload”
Firefox DevTools
-
View service workers:
- Navigate to
about:debugging#/runtime/this-firefox - Or DevTools → Application
- Navigate to
-
Unregister:
- Click “Unregister” next to the service worker
- Reload the page to re-register
Common Issues
Service worker not updating
Service worker not updating
- Increment the
CACHEversion insw.js - Hard refresh the page (Ctrl+Shift+R or Cmd+Shift+R)
- Check DevTools for service worker errors
- Use “Update on reload” during development
Assets not loading offline
Assets not loading offline
- Verify the asset path in the
ASSETSarray - Check that assets loaded successfully during install
- Look for CORS errors in the console
- Ensure the asset was visited/cached before going offline
Old cache persisting
Old cache persisting
- The
activateevent should clear old caches automatically - Manually delete caches in DevTools → Application → Cache Storage
- Verify the
CACHEconstant was changed - Check that
caches.delete()is working in the activate handler
CORS errors during caching
CORS errors during caching
- Remove external CDN resources from
ASSETSarray - Use local copies of third-party resources
- Ensure
Promise.allSettled()handles failures gracefully - External resources can still be fetched but won’t be cached
Best Practices
Development
- Enable “Update on reload” in DevTools during development
- Use “Bypass for network” to test without service worker interference
- Clear cache frequently to avoid stale content
- Test both online and offline scenarios
Production
- Bump
CACHEversion with every deployment - Keep the
ASSETSarray updated with new files - Monitor service worker errors in production logs
- Test the update flow before deploying
- Consider cache size limits (browsers vary, typically 50MB+)
Performance
- Cache only essential assets in the
ASSETSarray - Let dynamic caching handle additional resources
- Clone responses before caching to avoid stream issues
- Use cache-first strategy for static assets
- Consider network-first for frequently updated API data
API Reference
Constants
| Constant | Type | Description |
|---|---|---|
CACHE | string | Cache version identifier. Update to force cache refresh. |
ASSETS | string[] | Array of URLs to cache during service worker installation. |
Event Handlers
| Event | Handler | Purpose |
|---|---|---|
install | self.addEventListener('install', ...) | Caches initial assets when service worker installs |
activate | self.addEventListener('activate', ...) | Cleans up old caches when new version activates |
fetch | self.addEventListener('fetch', ...) | Intercepts network requests and serves from cache |
Methods Used
| Method | Description |
|---|---|
caches.open(name) | Opens a cache by name, creating it if it doesn’t exist |
caches.keys() | Returns a promise resolving to an array of cache names |
caches.delete(name) | Deletes a cache by name |
caches.match(request) | Returns a promise resolving to a cached response or undefined |
cache.add(url) | Fetches a URL and adds it to the cache |
cache.put(request, response) | Stores a request/response pair in the cache |
self.skipWaiting() | Forces the waiting service worker to become active |
self.clients.claim() | Takes control of all clients immediately |
Related Documentation
- Database API - IndexedDB operations that work offline
- Shared Functions - Utility functions used across pages
- PWA Configuration - Progressive Web App setup including manifest.json