Jak wdrożyć PWA (Progressive Web App)

Progressive Web App to nowoczesne rozwiązanie łączące zalety tradycyjnych stron internetowych i aplikacji mobilnych. Dzięki niemu użytkownicy mogą zainstalować witrynę na swoim urządzeniu, korzystać z niej offline oraz otrzymywać powiadomienia push. Artykuł opisuje, jak krok po kroku wdrożyć PWA, począwszy od przygotowania manifestu aż po strategie cache i testowanie wydajności.

Tworzenie pliku manifestu aplikacji

Manifest to plik JSON zawierający metadane aplikacji. Dzięki niemu przeglądarka wie, jak wyświetlić ikonę na ekranie głównym, jakie kolory zastosować w pasku adresu oraz jakie uprawnienia przyznać podczas instalacji.

  • Utwórz plik manifest.json w katalogu głównym projektu.
  • Wypełnij pola:
    • name – pełna nazwa aplikacji;
    • short_name – skrócona nazwa wyświetlana pod ikoną;
    • start_url – punkt wejścia, np. “/index.html”;
    • icons – tablica obiektów z różnymi rozmiarami ikon;
    • background_color – kolor tła podczas uruchamiania;
    • theme_color – kolor paska przeglądarki.
  • Zarejestruj manifest w pliku HTML:
    <link rel="manifest" href="/manifest.json">
  • Zadbaj o serwowanie manifestu z odpowiednim nagłówkiem Content-Type: application/manifest+json.

Rejestracja i konfiguracja Service Workera

Service Worker to skrypt pośredniczący między przeglądarką a siecią. Dzięki niemu można przechwycić żądania HTTP, zastosować mechanizmy cache i obsłużyć tryb offline.

Rejestracja

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(reg => console.log('Service Worker zarejestrowany', reg))
    .catch(err => console.error('Rejestracja SW nie powiodła się', err));
}

Podstawowe zdarzenia

  • install – instalacja SW, idealne miejsce na wstępne buforowanie plików;
  • activate – aktywacja nowej wersji SW i czyszczenie starych cache’ów;
  • fetch – przechwytywanie żądań sieciowych i zwracanie zasobów z pamięci podręcznej lub sieci.

Przykład pliku sw.js

const CACHE_NAME = 'app-cache-v1';
const URLS_TO_CACHE = [
  '/',
  '/index.html',
  '/styles.css',
  '/app.js',
  '/icons/icon-192.png'
];

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

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(keys => Promise.all(
      keys.filter(key => key !== CACHE_NAME)
          .map(key => caches.delete(key))
    ))
  );
});

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

Strategie buforowania i obsługa trybu offline

Dobrze dobrana strategia cache wpływa na szybkość aplikacji i oszczędność transferu. Oto najpopularniejsze podejścia:

  • Cache First – próba pobrania zasobu z pamięci podręcznej, a gdy brak, żądanie do sieci.
  • Network First – najpierw pobieranie z sieci (najświeższa wersja), a gdy brak odpowiedzi, z cache.
  • Stale-While-Revalidate – zwraca z cache, a w tle odświeża zasób z serwera.
  • Offline Page – zwrócenie specjalnej strony HTML, gdy użytkownik jest offline i żądany zasób nie jest dostępny.

Przykład implementacji strategii Stale-While-Revalidate:

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

Dostosowanie wyglądu i responsywność

Oprócz aspektów technicznych warto zadbać o komfort użytkownika. Kluczowe elementy to:

  • Responsywność – elastyczne siatki, media queries i adaptacja do różnych rozdzielczości;
  • Instalowalność – wyświetlanie banera zachęcającego do instalacji, warunkowo po spełnieniu wymagań PWA;
  • Animacje – łagodne przejścia między ekranami, wykorzystanie CSS Animations lub Web Animations API;
  • Dostępność – właściwe znaczniki ARIA, kontrast kolorów i czytelność czcionek.

Przykład metatagów ułatwiających integrację z Androidem:

<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="Moja PWA">
<meta name="theme-color" content="#317EFB">

Bezpieczeństwo i wymogi HTTPS

Domena z HTTPS to niezbędny warunek działania Service Workera. Certyfikat SSL gwarantuje integralność danych i chroni przed atakami typu MITM.

  • Uzyskaj certyfikat SSL (Let’s Encrypt, komercyjny) i skonfiguruj serwer.
  • Wymuś przekierowanie z HTTP na HTTPS.
  • Testuj bezpieczeństwo za pomocą narzędzi takich jak Qualys SSL Labs.

Dodatkowe funkcje i testowanie wydajności

Zaawansowane PWA oferują powiadomienia push, synchronizację w tle oraz integrację z natywnymi API. Warto również regularnie monitorować performance:

  • Powiadomienia Push – użycie Firebase Cloud Messaging lub innych serwisów;
  • Background Sync – opóźnione wysyłanie danych po odzyskaniu łączności;
  • Web App Install Banner – umożliwienie instalacji poprzez Event beforeinstallprompt;
  • Lighthouse – audyt w Chrome DevTools pod kątem PWA, dostępności i wydajności;
  • Web Vitals – monitorowanie najważniejszych wskaźników jakości UX.

Dzięki zastosowaniu powyższych technik Twoja aplikacja zyska cechy porównywalne z natywnymi rozwiązaniami, a użytkownicy docenią szybkość, responsywność i możliwość działania w trybie offline.