乐闻世界logo
搜索文章和话题

How does Service Worker implement offline access functionality?

3月7日 12:05

Service Worker Offline Access Implementation

Offline access is one of the core features of Service Worker, allowing web applications to work normally without network connectivity.

Core Principle

Service Worker acts as a network proxy, intercepting all HTTP requests and deciding whether to return from cache or request from network based on caching strategies.

Implementation Steps

1. Register Service Worker

javascript
// main.js if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js') .then(registration => { console.log('SW registered:', registration.scope); }) .catch(error => { console.log('SW registration failed:', error); }); }); }

2. Precache Core Resources

javascript
// sw.js const CACHE_NAME = 'offline-cache-v1'; const urlsToCache = [ '/', '/index.html', '/styles.css', '/app.js', '/icons/icon-192x192.png', '/offline.html' // Offline fallback page ]; self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => { console.log('Cache opened'); return cache.addAll(urlsToCache); }) .catch(err => console.error('Cache failed:', err)) ); self.skipWaiting(); });

3. Intercept Requests and Return Cache

javascript
self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request) .then(response => { // Cache hit, return directly if (response) { return response; } // Cache miss, request from network return fetch(event.request) .then(networkResponse => { // Dynamically cache new resources if (!networkResponse || networkResponse.status !== 200) { return networkResponse; } const responseToCache = networkResponse.clone(); caches.open(CACHE_NAME).then(cache => { cache.put(event.request, responseToCache); }); return networkResponse; }) .catch(() => { // Network failed, return offline page if (event.request.mode === 'navigate') { return caches.match('/offline.html'); } }); }) ); });

4. Clean Old Caches

javascript
self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames .filter(name => name !== CACHE_NAME) .map(name => caches.delete(name)) ); }) ); self.clients.claim(); });

Offline Page Design

html
<!-- offline.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Offline Mode</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial, sans-serif; background: #f5f5f5; } .offline-container { text-align: center; padding: 40px; } .offline-icon { font-size: 64px; margin-bottom: 20px; } h1 { color: #333; } p { color: #666; } button { padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } </style> </head> <body> <div class="offline-container"> <div class="offline-icon">📡</div> <h1>You are currently offline</h1> <p>Please check your network connection and try again</p> <button onclick="location.reload()">Reload</button> </div> </body> </html>

Advanced Offline Strategies

1. Network First + Cache Fallback

javascript
self.addEventListener('fetch', event => { event.respondWith( fetch(event.request) .then(response => { // Update cache const clone = response.clone(); caches.open(CACHE_NAME).then(cache => { cache.put(event.request, clone); }); return response; }) .catch(() => caches.match(event.request)) ); });

2. Cache First + Background Update

javascript
self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(response => { const fetchPromise = fetch(event.request).then(networkResponse => { caches.open(CACHE_NAME).then(cache => { cache.put(event.request, networkResponse.clone()); }); return networkResponse; }); return response || fetchPromise; }) ); });

Network Status Detection

javascript
// Detect in main thread window.addEventListener('online', () => { console.log('Network connected'); }); window.addEventListener('offline', () => { console.log('Network disconnected'); }); // Check current status if (navigator.onLine) { console.log('Online'); } else { console.log('Offline'); }

Best Practices

  1. Core Resources First: Ensure HTML, CSS, JS and other core resources are cached
  2. Graceful Degradation: Provide friendly offline page when network fails
  3. Cache Updates: Regularly update cache to prevent users from seeing old versions
  4. Cache Cleanup: Clean expired caches to avoid storage overflow
  5. Testing: Use Chrome DevTools Network panel to simulate offline environment
标签:Service Worker