Offline-Modus und Caching verstehen
Wie LobbyFlight mit Verbindungsunterbrechungen umgeht und Daten intelligent zwischenspeichert
Offline-Modus und Caching verstehen
LobbyFlight ist für 24/7-Betrieb ausgelegt und kann Netzwerkunterbrechungen intelligent handhaben. Diese Anleitung erklärt die mehrstufige Caching-Architektur und Offline-Funktionalität.
Service Worker Architektur
Das Herzstück der Offline-Funktionalität ist der Service Worker - ein JavaScript-Prozess, der zwischen Browser und Netzwerk vermittelt.
Die drei Cache-Ebenen
LobbyFlight verwendet drei spezialisierte Cache-Speicher:
1. CACHE_NAME (lobbyflight-v1)
Zweck: Speichert essenzielle App-Ressourcen
Inhalt:
Lebensdauer: Bis zum nächsten App-Update
2. RUNTIME_CACHE
Zweck: Dynamisch generierte Inhalte
Inhalt:
Lebensdauer: Automatisches Cleanup bei Update
3. API_CACHE
Zweck: API-Responses mit Zeitstempel
Inhalt:
Besonderheit: Jeder Cache-Eintrag erhält Zeitstempel für Aktualitätsprüfung
Caching-Strategien im Detail
API-Requests: Network-First, Cache-Fallback
Ablauf:
Code-Beispiel:
// Vereinfachte Darstellung
fetch(apiRequest)
.then(response => {
cache.put(apiRequest, response.clone())
return response
})
.catch(() => {
return cache.match(apiRequest) || offlineFallback
})Vorteile:
Static Assets: Cache-First, Network-Fallback
Ablauf:
Performance-Vorteil:
Navigation: Offline-Page als Fallback
Ablauf:
Was wird automatisch gecacht?
Bei der Installation (Precaching)
Folgende Ressourcen werden sofort beim ersten Besuch gecacht:
Core-Assets:
/ # Startseite
/offline # Offline-Fallback-Seite
/_next/static/css/*.css # Alle Stylesheets
/_next/static/js/*.js # JavaScript-Bundles
/logo.png # Hotel-Logo
/fonts/*.woff2 # Web-Schriften
/manifest.json # PWA-ManifestGröße: Typisch 2-3 MB
Während des Betriebs (Runtime Caching)
Diese Inhalte werden bei Nutzung automatisch gecacht:
Flugdaten
Endpoint: /api/flights/[hotelId]?type=departures
Endpoint: /api/flights/[hotelId]?type=arrivals
Cache-Dauer: Unbegrenzt (wird bei Update überschrieben)
Größe: ~50KB pro RequestKonfiguration
Endpoint: /api/config/[hotelId]
Cache-Dauer: Unbegrenzt
Größe: ~5KB
Update: Alle 60 Sekunden bei OnlineWetterdaten (wenn aktiviert)
Endpoint: /api/weather/[airportCode]
Cache-Dauer: Unbegrenzt
Größe: ~10KB
Update: Alle 30 Minuten bei OnlineHotel-Assets
Logo: *.blob.vercel-storage.com/logo.png
Info-Slide-Bilder: *.blob.vercel-storage.com/slides/*
Cache-Dauer: 7 Tage
Größe: Variable (100KB-1MB pro Bild)API-Response Caching Details
Zeitstempel-System
Jede gecachte API-Response erhält Metadaten:
headers.set('sw-cached-at', '2024-01-15T10:30:00Z')
headers.set('sw-cache-version', 'v1')
headers.set('sw-original-url', request.url)Intelligente Cache-Nutzung
Online-Verhalten:
Offline-Verhalten:
Cache-Alterung und Frische
Keine automatische Expiration!
Caches verfallen nicht automatisch. Stattdessen:
Visuelle Offline-Indikatoren
LobbyFlight zeigt den Verbindungsstatus deutlich an:
1. Status-Bar (Oberer Bildschirmrand)
Offline-Modus aktiv:
[Orange Bar] ⚠️ Offline Mode - Displaying cached flight data
Last sync: 10:45 (15 minutes ago)Eigenschaften:
2. Toast-Benachrichtigungen
Bei Verbindungsverlust:
[Rote Toast] ❌ Connection lost - Showing cached dataBei Wiederverbindung:
[Grüne Toast] ✅ Connection restored - Updating data...Eigenschaften:
3. Corner-Indikator (Unten links)
Pulsierender Punkt mit Label:
🔴 OfflineAnimation:
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}4. Daten-Aktualität-Anzeige
Bei gecachten Daten wird das Alter angezeigt:
Letzte Aktualisierung: vor 5 Minuten
Flugdaten: Stand 10:45 Uhr
Wetter: Stand 10:30 UhrAutomatische Wiederverbindung
Zwei Mechanismen arbeiten parallel:
1. Browser Online/Offline Events
JavaScript Event Listener:
window.addEventListener('online', () => {
// Sofort Updates holen
refreshAllData()
showToast('Connection restored', 'success')
})
window.addEventListener('offline', () => {
// Auf Cache-Modus wechseln
enableOfflineMode()
showToast('Connection lost', 'warning')
})Vorteile:
2. Periodische Health-Checks
Aktiver Connectivity-Test:
setInterval(async () => {
try {
const response = await fetch('/api/health', {
method: 'HEAD',
cache: 'no-cache'
})
if (!response.ok) throw new Error()
setOnlineStatus(true)
} catch {
setOnlineStatus(false)
}
}, 30000) // Alle 30 SekundenWarum zusätzliche Health-Checks?
Offline-Page Auto-Reload
Die Offline-Fallback-Seite versucht automatisch, die Verbindung wiederherzustellen:
Reconnection-Strategie:
JavaScript-Implementation:
let attempts = 0
const maxAttempts = 120
function tryReconnect() {
if (attempts >= maxAttempts) {
showMessage('Please reload manually')
return
}
fetch('/api/health')
.then(() => window.location.reload())
.catch(() => {
attempts++
const delay = attempts < 30 ? 1000 :
attempts < 60 ? 5000 : 30000
setTimeout(tryReconnect, delay)
})
}Cache-Management
Automatisches Cleanup
Service Worker führt automatische Bereinigung durch:
Bei Update der App:
Code:
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(name => name !== CURRENT_CACHE)
.map(name => caches.delete(name))
)
})
)
})Manuelles Cache-Löschen
Methode 1: Über Browser DevTools
Methode 2: Über JavaScript Console
// Alle Caches löschen
caches.keys().then(names => {
names.forEach(name => caches.delete(name))
})
// Service Worker neu registrieren
navigator.serviceWorker.getRegistration().then(reg => {
reg.unregister()
window.location.reload()
})Methode 3: Hard Refresh
Methode 4: Message API
// Cache-Clear-Nachricht an Service Worker
navigator.serviceWorker.controller.postMessage({
type: 'CLEAR_CACHE',
cache: 'all' // oder 'api', 'assets', 'runtime'
})Cache-Größen-Management
Browser-Limits:
LobbyFlight typische Nutzung:
Automatisches Eviction:
Browser löscht automatisch alte Caches wenn:
Troubleshooting Offline-Probleme
Problem: Alte Daten werden angezeigt
Symptome:
Diagnose:
Lösungen:
Problem: Offline-Modus trotz Internet
Symptome:
Diagnose:
Lösungen:
Problem: Service Worker lädt nicht
Symptome:
Diagnose:
// In Console ausführen
navigator.serviceWorker.getRegistrations().then(regs => {
console.log('Registered SWs:', regs)
})Lösungen:
Problem: Cache wird zu groß
Symptome:
Diagnose:
// Cache-Größe prüfen
navigator.storage.estimate().then(estimate => {
console.log(`Used: ${estimate.usage / 1024 / 1024}MB`)
console.log(`Quota: ${estimate.quota / 1024 / 1024}MB`)
})Lösungen:
Best Practices für Offline-Betrieb
Optimale Konfiguration
Für stabiles Netzwerk:
Für instabiles Netzwerk:
Vorbereitung auf Offline
Vor dem Deployment:
Regelmäßige Wartung:
Monitoring
Was überwachen:
Alert-Schwellen:
Erweiterte Konfiguration
Custom Offline-Page
Sie können eine eigene Offline-Seite gestalten:
HTML-Template (/public/custom-offline.html):
<!DOCTYPE html>
<html>
<head>
<title>Offline - [Hotel Name]</title>
<style>
/* Ihr Custom Styling */
</style>
</head>
<body>
<div class="container">
<img src="/logo.png" alt="Hotel Logo">
<h1>Momentan keine Verbindung</h1>
<p>Zeige gespeicherte Flugdaten...</p>
<div id="last-update"></div>
</div>
<script>
// Custom Reconnect-Logic
</script>
</body>
</html>Cache-Strategien anpassen
Für spezielle Anforderungen:
// Längere Cache-Zeit für Bilder
if (request.destination === 'image') {
return caches.match(request) || fetch(request).then(response => {
cache.put(request, response.clone())
return response
})
}
// Kein Cache für bestimmte APIs
if (request.url.includes('/realtime/')) {
return fetch(request) // Immer frisch
}Offline-Analytics
Tracking von Offline-Events:
// Bei Offline
navigator.sendBeacon('/api/analytics', JSON.stringify({
event: 'offline_start',
timestamp: new Date().toISOString(),
cached_items: await countCachedItems()
}))
// Bei Reconnect
navigator.sendBeacon('/api/analytics', JSON.stringify({
event: 'offline_end',
duration: offlineDuration,
cache_hits: cacheHitCount
}))