Artikel

Service Workers — Offline caching og PWA performance

Service Workers intercepter netværkskald og cacher ressourcer lokalt. Returnerende brugere oplever øjeblikkelig indlæsning — TTFB og LCP reduceres til nul for cachede sider.

En Service Worker er en scriptbar netværks-proxy der kører i baggrunden. Den intercept-er alle netværkskald fra din side og kan svare med cachede ressourcer, modificere requests eller fallback til en offline-side. For returnerende brugere er det den mest effektive performance-teknik: TTFB og LCP reduceres til nul for ressourcer der serveres fra Service Worker-cachen.

Livscyklus

Service Workers gennemgår en defineret livscyklus:

  1. Registration — siden registrerer Service Worker-scriptet
  2. Installation — SW downloader og cacher definerede ressourcer (precaching)
  3. Activation — SW overtager kontrol over siden
  4. Fetch interception — SW intercepter fremtidige netværkskald
// Registrer Service Worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js');
  });
}

Caching-strategier

Der er etablerede strategier for hvornår og hvad der caches:

Cache First (cache falling back to network)

Servér fra cache. Netværket er fallback. Optimal for statiske assets der sjældent ændres:

// sw.js
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((cached) => {
      return cached || fetch(event.request);
    })
  );
});

Network First (network falling back to cache)

Forsøg netværket. Fald tilbage til cache hvis netværket fejler. Optimal for API-kald og dynamisk indhold:

self.addEventListener('fetch', (event) => {
  event.respondWith(
    fetch(event.request).catch(() => caches.match(event.request))
  );
});

Stale While Revalidate

Servér cached version øjeblikkeligt. Opdatér cache i baggrunden. Balancerer friskhed og hastighed:

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.open('v1').then((cache) => {
      return cache.match(event.request).then((cached) => {
        const networkFetch = fetch(event.request).then((response) => {
          cache.put(event.request, response.clone());
          return response;
        });
        return cached || networkFetch;
      });
    })
  );
});

Precaching ved installation

Cache kritiske ressourcer ved SW-installation — de er tilgængelige øjeblikkeligt ved første visit efter:

const CACHE_NAME = 'v1';
const PRECACHE_URLS = ['/', '/offline.html', '/styles.css', '/app.js'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll(PRECACHE_URLS))
  );
});

Offline fallback

En offline-side der vises når brugeren er offline og siden ikke er cached:

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request).catch(() => caches.match('/offline.html'))
    );
  }
});

Workbox — praktisk Service Worker bibliotek

Manuel Service Worker-implementering er fejlprone. Workbox (Google) abstraherer caching-strategier til deklarative konfigurationer:

import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate, CacheFirst } from 'workbox-strategies';

registerRoute(
  ({ request }) => request.destination === 'image',
  new CacheFirst({ cacheName: 'images' })
);

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({ cacheName: 'api-cache' })
);

Performance-implikationen

For returnerende brugere serveret fra Service Worker cache:

  • TTFB: ~0ms (lokal cache)
  • LCP: reduceres markant — kritiske assets er lokale
  • Offline: siden fungerer uden netværk

Google Lighthouse auditerer Service Worker-implementering under PWA-kategorien. En velfungerende SW forbedrer ikke direkte Core Web Vitals-scores i lab-tests (Lighthouse kører som first visit) men har markant effekt på field data for returnerende brugere. → Denne artikel er en del af Web Performance — Core Web Vitals og teknisk hastighed.

Andre artikler i samme emne

Ofte stillede spørgsmål

Hvad er en Service Worker?
En Service Worker er et JavaScript-script der kører i en separat browser-thread og fungerer som en proxy mellem webapplikationen og netværket. Den kan intercepte, cache og manipulere netværkskald — også når siden er lukket. Service Workers kræver HTTPS (undtagen localhost) og er en del af Progressive Web App-specifikationen.
Hvad er forskellen på Service Worker caching og HTTP caching?
HTTP caching styres af Cache-Control-headeren og er browser-kontrolleret. Service Worker caching er applikations-kontrolleret via Cache Storage API — du bestemmer præcist hvilke ressourcer der caches, hvornår de opdateres og hvad der serveres når netværket er utilgængeligt. Service Workers kan servere offline fallback-sider, HTTP caching kan ikke.
Påvirker Service Workers SEO og Googlebots crawling?
Service Workers kan i princippet intercepte Googlebots requests og servere andet indhold end det brugere ser — det er cloaking og en overtrædelse af Googles retningslinjer. I praksis kører Googlebot med fetch-mode 'navigate' og ignorerer typisk Service Workers i crawl-fasen. Men implementeringer der returnerer cached stale-content til Googlebot mens brugere ser frisk indhold kan skabe forvirring. Hold Service Worker-logik separat fra indholdslevering til Googlebot.
Hvad er Stale While Revalidate og hvornår er det bedst?
Stale While Revalidate serverer cached version øjeblikkeligt og opdaterer cachen i baggrunden via et parallelt netværkskald. Brugeren oplever nul ventetid men ser muligvis indhold der er op til én cache-periode gammelt. Det er den bedste strategi til ressourcer der ændres jævnligt men ikke behøver at være 100% friske — blogindlæg, kategori-sider, ikke-kritiske API-kald. Til prisinformation eller lagerstatus er Network First bedre.
Hvad er Workbox og hvornår er det værd at bruge?
Workbox er Googles JavaScript-bibliotek der abstraherer Service Worker-implementering til deklarative konfigurationer. Det håndterer precaching, caching-strategier, opdateringscyklusser og cache-invalidering uden at du skriver boilerplate-kode manuelt. Workbox er standardanbefalingen for alle produktionsprojekter — manuel Service Worker-implementering er fejlpron og svær at vedligeholde. Workbox integrerer direkte med Webpack, Vite og Rollup via plugins.

Placering i ordbogen

Service Workers — Offline caching og PWA performance