Cloud-Native

Service Worker Implementierung: Schritt-für-Schritt Anleitung mit Workbox

Praktische Anleitung zur Service Worker Implementierung mit Workbox: Setup, Registrierung, Caching und Integration in Vue, React und Angular.

C
CFTools Software
Autor
30. Januar 2026
7 min Lesezeit

Service Worker Implementierung

Diese Anleitung zeigt die Implementierung eines Service Workers mit Workbox für moderne SPA-Frameworks.

Voraussetzungen

  • Node.js 18+
  • HTTPS-Umgebung (oder localhost)
  • Build-Tool (Vite, Webpack, etc.)
  • Grundkenntnisse JavaScript/TypeScript

Schritt 1: Workbox Installation

# npm
npm install workbox-core workbox-routing workbox-strategies 
npm install workbox-precaching workbox-expiration
npm install -D vite-plugin-pwa  # Für Vite

# yarn
yarn add workbox-core workbox-routing workbox-strategies
yarn add workbox-precaching workbox-expiration
yarn add -D vite-plugin-pwa

Schritt 2: Service Worker erstellen

Basis-Setup (sw.ts)

// src/sw.ts
import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate, NetworkFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';

declare let self: ServiceWorkerGlobalScope;

// Versionierung
const CACHE_VERSION = 'v1';

// Alte Caches bereinigen
cleanupOutdatedCaches();

// Precaching (von Build-Tool generiert)
precacheAndRoute(self.__WB_MANIFEST);

// Statische Assets: Cache First
registerRoute(
  ({ request }) => 
    request.destination === 'script' ||
    request.destination === 'style',
  new CacheFirst({
    cacheName: `static-${CACHE_VERSION}`,
    plugins: [
      new ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 60 * 60 * 24 * 30, // 30 Tage
      }),
    ],
  })
);

// Fonts: Cache First mit langer TTL
registerRoute(
  ({ request }) => request.destination === 'font',
  new CacheFirst({
    cacheName: `fonts-${CACHE_VERSION}`,
    plugins: [
      new ExpirationPlugin({
        maxEntries: 20,
        maxAgeSeconds: 60 * 60 * 24 * 365, // 1 Jahr
      }),
    ],
  })
);

// Bilder: Cache First
registerRoute(
  ({ request }) => request.destination === 'image',
  new CacheFirst({
    cacheName: `images-${CACHE_VERSION}`,
    plugins: [
      new ExpirationPlugin({
        maxEntries: 100,
        maxAgeSeconds: 60 * 60 * 24 * 30, // 30 Tage
      }),
    ],
  })
);

// API: Stale-While-Revalidate
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    cacheName: `api-${CACHE_VERSION}`,
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200],
      }),
      new ExpirationPlugin({
        maxEntries: 100,
        maxAgeSeconds: 60 * 60, // 1 Stunde
      }),
    ],
  })
);

Schritt 3: Framework-Integration

Vue 3 + Vite

// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    vue(),
    VitePWA({
      registerType: 'autoUpdate',
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
        runtimeCaching: [
          {
            urlPattern: /^https:\/\/api\.example\.com\/.*$/,
            handler: 'StaleWhileRevalidate',
            options: {
              cacheName: 'api-cache',
              expiration: {
                maxEntries: 100,
                maxAgeSeconds: 60 * 60,
              },
            },
          },
        ],
      },
      manifest: {
        name: 'Meine App',
        short_name: 'App',
        theme_color: '#ffffff',
        icons: [
          {
            src: '/icon-192.png',
            sizes: '192x192',
            type: 'image/png',
          },
          {
            src: '/icon-512.png',
            sizes: '512x512',
            type: 'image/png',
          },
        ],
      },
    }),
  ],
});

React + Vite

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      strategies: 'injectManifest',
      srcDir: 'src',
      filename: 'sw.ts',
      injectManifest: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
      },
    }),
  ],
});

Angular

# Angular PWA Schematic
ng add @angular/pwa
// ngsw-config.json
{
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**"
        ]
      }
    }
  ],
  "dataGroups": [
    {
      "name": "api",
      "urls": ["/api/**"],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 100,
        "maxAge": "1h"
      }
    }
  ]
}

Schritt 4: Registrierung

Manuelle Registrierung

// src/registerSW.ts
export async function registerServiceWorker() {
  if (!('serviceWorker' in navigator)) {
    console.warn('Service Worker nicht unterstützt');
    return;
  }

  try {
    const registration = await navigator.serviceWorker.register('/sw.js', {
      scope: '/',
    });

    // Update-Handling
    registration.addEventListener('updatefound', () => {
      const newWorker = registration.installing;
      
      newWorker?.addEventListener('statechange', () => {
        if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
          // Neuer SW verfügbar
          showUpdateNotification();
        }
      });
    });

    console.log('Service Worker registriert:', registration.scope);
  } catch (error) {
    console.error('SW Registrierung fehlgeschlagen:', error);
  }
}

Mit vite-plugin-pwa

// src/main.ts
import { registerSW } from 'virtual:pwa-register';

const updateSW = registerSW({
  onNeedRefresh() {
    // Benutzer fragen, ob aktualisiert werden soll
    if (confirm('Neue Version verfügbar. Jetzt aktualisieren?')) {
      updateSW(true);
    }
  },
  onOfflineReady() {
    console.log('App ist offline-bereit');
  },
});

Schritt 5: Update-Strategie

skipWaiting + clients.claim

// sw.ts
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

self.addEventListener('activate', (event) => {
  event.waitUntil(self.clients.claim());
});

Prompt-basiertes Update

// In der App
function promptUpdate(registration: ServiceWorkerRegistration) {
  const toast = document.createElement('div');
  toast.innerHTML = `
    <p>Neue Version verfügbar</p>
    <button id="update">Aktualisieren</button>
    <button id="dismiss">Später</button>
  `;
  
  document.getElementById('update')?.addEventListener('click', () => {
    registration.waiting?.postMessage({ type: 'SKIP_WAITING' });
    window.location.reload();
  });
}

Wichtige Befehle

# Build mit SW-Generierung
npm run build

# Entwicklung (SW deaktiviert)
npm run dev

# Produktion lokal testen
npm run preview

# SW im Browser deregistrieren (DevTools)
# Application > Service Workers > Unregister

Debugging

Chrome DevTools

  1. Application Tab > Service Workers
  2. Aktive SW, Waiting SW, Update-Status sichtbar
  3. "Update on reload" für Entwicklung aktivieren

Nützliche Logs

// sw.ts
self.addEventListener('install', (event) => {
  console.log('[SW] Installing version:', CACHE_VERSION);
});

self.addEventListener('activate', (event) => {
  console.log('[SW] Activating version:', CACHE_VERSION);
});

self.addEventListener('fetch', (event) => {
  console.log('[SW] Fetching:', event.request.url);
});

Nächste Schritte

  • Push-Benachrichtigungen implementieren
  • Background Sync einrichten
  • Offline-Fallback-Seite erstellen
  • Cache-Analytics integrieren
  • Performance-Monitoring

Verwandte Themen

  • Workbox-Dokumentation
  • PWA-Manifest
  • Cache API
  • vite-plugin-pwa
  • @angular/pwa

CFTools Software unterstützt bei der Service Worker Implementierung für Enterprise-Anwendungen.

Tags:
Service Worker
Workbox
PWA
Vue
React
Implementation
Tutorial
C

CFTools Software

Geschäftsführer und Gründer von CFTools Software GmbH. Leidenschaftlich in der Entwicklung skalierbarer Softwarelösungen und Cloud-Native-Architekturen.

Artikel nicht verfügbar

Dieser Artikel ist für Ihren Zugangstyp nicht verfügbar.

Alle Artikel anzeigen