Architectuur van Progressive Web Apps: Patronen voor JavaScript Service Workers | MLOG | MLOG

4. Network-Only

De network-only-strategie haalt bestanden altijd van het netwerk op, waarbij de cache volledig wordt overgeslagen. Deze strategie wordt gebruikt wanneer u absoluut de nieuwste versie van een bron nodig heeft en caching niet gewenst is.

Voorbeeld:

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

            

5. Stale-While-Revalidate

De stale-while-revalidate-strategie levert het gecachte bestand onmiddellijk en haalt tegelijkertijd de nieuwste versie van het netwerk op. Zodra het netwerkverzoek is voltooid, wordt de cache bijgewerkt met de nieuwe versie. Deze strategie biedt een snelle initiële respons en zorgt er tegelijkertijd voor dat de gebruiker uiteindelijk de meest up-to-date content ontvangt. Dit is een nuttige strategie voor niet-kritieke content die meer profiteert van snelheid dan van absolute actualiteit.

Voorbeeld:

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

            

6. Cache, then Network

Vergelijkbaar met stale-while-revalidate, maar zonder de onmiddellijke teruggave van het gecachte bestand. Het controleert eerst de cache, en alleen als het bestand aanwezig is, wordt het netwerkverzoek op de achtergrond uitgevoerd om de cache bij te werken.

De juiste cachingstrategie kiezen

De optimale cachingstrategie hangt af van de specifieke eisen van uw applicatie. Houd rekening met factoren zoals:

Door zorgvuldig de juiste cachingstrategieën te selecteren, kunt u de prestaties en gebruikerservaring van uw PWA aanzienlijk verbeteren, zelfs in offline omgevingen. Tools zoals Workbox ([https://developers.google.com/web/tools/workbox](https://developers.google.com/web/tools/workbox)) kunnen de implementatie van deze strategieën vereenvoudigen.

Achtergrondsynchronisatie: Omgaan met offline mutaties

Achtergrondsynchronisatie stelt uw PWA in staat om taken op de achtergrond uit te voeren, zelfs als de gebruiker offline is. Dit is met name handig voor het afhandelen van formulierinzendingen, data-updates en andere operaties die netwerkconnectiviteit vereisen. De `BackgroundSyncManager` API stelt u in staat om taken te registreren die worden uitgevoerd wanneer het netwerk beschikbaar komt.

Een achtergrondsynchronisatietaak registreren

Om een achtergrondsynchronisatietaak te registreren, moet u de `register`-methode van de `BackgroundSyncManager` gebruiken. Deze methode accepteert een unieke tagnaam als argument. De tagnaam identificeert de specifieke taak die moet worden uitgevoerd.

Voorbeeld:

            
self.addEventListener('sync', event => {
  if (event.tag === 'my-sync-task') {
    event.waitUntil(doSomeWork());
  }
});

            

Het sync-event afhandelen

Wanneer de browser netwerkconnectiviteit detecteert, stuurt het een `sync`-event naar de service worker. U kunt naar dit event luisteren en de benodigde acties uitvoeren, zoals het verzenden van data naar de server.

Voorbeeld:

            
async function doSomeWork() {
  // Retrieve data from IndexedDB
  const data = await getDataFromIndexedDB();

  // Send data to the server
  try {
    const response = await fetch('/api/sync', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    });

    if (response.ok) {
      // Clear the data from IndexedDB
      await clearDataFromIndexedDB();
    } else {
      // Handle errors
      console.error('Sync failed:', response.status);
      throw new Error('Sync failed');
    }
  } catch (error) {
    // Handle network errors
    console.error('Network error:', error);
    throw error;
  }
}

            

Voorbeeld: Offline formulierinzending

Stel u een scenario voor waarin een gebruiker een formulier invult terwijl hij offline is. De service worker kan de formulierdata opslaan in IndexedDB en een achtergrondsynchronisatietaak registreren. Wanneer het netwerk beschikbaar komt, haalt de service worker de formulierdata op uit IndexedDB en verzendt deze naar de server.

  1. De gebruiker vult het formulier in en klikt op verzenden terwijl hij offline is.
  2. De formulierdata wordt opgeslagen in IndexedDB.
  3. Er wordt een achtergrondsynchronisatietaak geregistreerd met een unieke tag (bijv. `form-submission`).
  4. Wanneer het netwerk beschikbaar is, wordt het `sync`-event geactiveerd.
  5. De service worker haalt de formulierdata op uit IndexedDB en verzendt deze naar de server.
  6. Als de verzending succesvol is, wordt de formulierdata uit IndexedDB verwijderd.

Pushmeldingen: Gebruikers betrekken met tijdige updates

Pushmeldingen stellen uw PWA in staat om tijdige updates en berichten naar gebruikers te sturen, zelfs wanneer de app niet actief in de browser draait. Dit kan de gebruikersbetrokkenheid en -retentie aanzienlijk verbeteren. De Push API en Notifications API werken samen om pushmeldingen te leveren.

Abonneren op pushmeldingen

Om pushmeldingen te ontvangen, moeten gebruikers eerst toestemming geven aan uw PWA. U kunt de `PushManager` API gebruiken om gebruikers te abonneren op pushmeldingen.

Voorbeeld:

            
navigator.serviceWorker.ready.then(registration => {
  registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: 'YOUR_PUBLIC_VAPID_KEY'
  })
  .then(subscription => {
    // Send subscription details to your server
    sendSubscriptionToServer(subscription);
  })
  .catch(error => {
    console.error('Failed to subscribe:', error);
  });
});

            

Belangrijk: Vervang `YOUR_PUBLIC_VAPID_KEY` door uw daadwerkelijke VAPID-sleutel (Voluntary Application Server Identification). VAPID-sleutels worden gebruikt om uw applicatieserver te identificeren en ervoor te zorgen dat pushmeldingen veilig worden verzonden.

Pushmeldingen afhandelen

Wanneer een pushmelding wordt ontvangen, stuurt de service worker een `push`-event. U kunt naar dit event luisteren en de melding aan de gebruiker tonen.

Voorbeeld:

            
self.addEventListener('push', event => {
  const payload = event.data ? event.data.text() : 'No payload';

  event.waitUntil(
    self.registration.showNotification('My PWA', {
      body: payload,
      icon: 'icon.png'
    })
  );
});

            

Pushmeldingen aanpassen

Met de Notifications API kunt u het uiterlijk en het gedrag van pushmeldingen aanpassen. U kunt de titel, body, icoon, badge en andere opties specificeren.

Voorbeeld:

            
self.addEventListener('push', event => {
  const data = event.data.json();
  const title = data.title || 'My PWA';
  const options = {
    body: data.body || 'No message',
    icon: data.icon || 'icon.png',
    badge: data.badge || 'badge.png',
    vibrate: [200, 100, 200],
    data: { // Aangepaste data die je kunt benaderen wanneer de gebruiker op de melding klikt
      url: data.url || '/'
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'Close',
        icon: 'images/xmark.png'},
    ]
  };

  event.waitUntil(self.registration.showNotification(title, options));
});


self.addEventListener('notificationclick', function(event) {
  event.notification.close();

  // Controleer of de gebruiker op een actie heeft geklikt.
  if (event.action === 'explore') {
    clients.openWindow(event.notification.data.url);
  } else {
    // Standaardactie: open de app.
    clients.openWindow('/');
  }
});

            

Voorbeeld: Nieuwsmelding

Een nieuwsapplicatie kan pushmeldingen gebruiken om gebruikers te waarschuwen voor breaking news. Wanneer een nieuw artikel wordt gepubliceerd, stuurt de server een pushmelding naar het apparaat van de gebruiker met een korte samenvatting van het artikel. De gebruiker kan vervolgens op de melding klikken om het volledige artikel in de PWA te openen.

Geavanceerde Service Worker-patronen

1. Offline Analytics

Volg het gedrag van gebruikers, zelfs wanneer ze offline zijn, door analytics-data lokaal op te slaan en naar de server te sturen wanneer het netwerk beschikbaar is. Dit kan worden bereikt met behulp van IndexedDB en Background Sync.

2. Versiebeheer en updates

Implementeer een robuuste versiebeheerstrategie voor uw service worker om ervoor te zorgen dat gebruikers altijd de nieuwste updates ontvangen zonder hun ervaring te verstoren. Gebruik 'cache busting'-technieken om oude gecachte bestanden ongeldig te maken.

3. Modulaire Service Workers

Organiseer uw service worker-code in modules om de onderhoudbaarheid en leesbaarheid te verbeteren. Gebruik JavaScript-modules (ESM) of een module bundler zoals Webpack of Rollup.

4. Dynamische Caching

Cache bestanden dynamisch op basis van gebruikersinteracties en gebruikspatronen. Dit kan helpen de cachegrootte te optimaliseren en de prestaties te verbeteren.

Best Practices voor de ontwikkeling van Service Workers

Conclusie

JavaScript service workers zijn krachtige tools voor het bouwen van robuuste, performante en boeiende PWA's. Door de levenscyclus van de service worker te begrijpen en de juiste cachingstrategieën, achtergrondsynchronisatie en pushmeldingen te implementeren, kunt u uitzonderlijke gebruikerservaringen creëren, zelfs in offline omgevingen. Dit artikel heeft belangrijke service worker-patronen en best practices onderzocht om u te begeleiden bij het bouwen van succesvolle PWA's voor een wereldwijd publiek. Naarmate het web zich verder ontwikkelt, zullen service workers een steeds belangrijkere rol spelen in de toekomst van webontwikkeling.

Vergeet niet om deze patronen aan te passen aan de specifieke eisen van uw applicatie en geef altijd prioriteit aan de gebruikerservaring. Door de kracht van service workers te omarmen, kunt u PWA's creëren die niet alleen functioneel zijn, maar ook prettig in gebruik, ongeacht de locatie of netwerkverbinding van de gebruiker.

Verdere bronnen: