Belajar Frontend - PWA & Offline First
Episode 22 of 28

Belajar Frontend - PWA & Offline First

Membuat aplikasi web berfungsi penuh offline dengan PWA: service workers dan siklus hidupnya, strategi caching (network-first, cache-first, stale-while-revalidate), kriteria installability, dan penerapan offline di TokoKita

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Koneksi internet tidak selalu stabil — terutama untuk pengguna mobile. Episode 22 membahas PWA (Progressive Web Apps): aplikasi web yang bisa diinstall, bekerja offline, dan dimuat seketika berkat service workers. Ini bukan tren: PWA adalah strategi bisnis nyata untuk produk yang menjangkau pengguna di koneksi lambat.

Mengapa episode ini penting untuk TokoKita? Karena pengunjung dengan koneksi buruk adalah pengguna nyata. Aplikasi yang "berfungsi tanpa internet" untuk konten yang pernah dibuka, plus ikon di homescreen, mengubah web dari "halaman" menjadi "aplikasi" — pengalaman yang pengguna harapkan dari produk serius.

Apa Itu PWA

PWA adalah web app dengan tiga syarat inti:

  1. Reliable — muat instan, bisa dipakai offline (service worker).
  2. Installable — punya manifest, bisa ditambahkan ke homescreen.
  3. Engaging — push notification, ikon, dan pengalaman seperti aplikasi native.

Web app "biasa" yang dipakai tanpa koneksi → blank page. PWA yang pernah dikunjungi → tetap berfungsi dari cache.

Service Workers: Otak PWA

Service worker adalah script yang berjalan terpisah dari halaman dan bertindak sebagai proxy antara browser dan jaringan. Ia menjalankan tiga event utama:

sw.ts — siklus hidup service worker
// INSTALL — simpan aset inti (shell aplikasi)
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open("toko-kita-v1").then((cache) =>
      cache.addAll(["/", "/products", "/offline.html"])
    )
  );
  self.skipWaiting();
});
 
// ACTIVATE — bersihkan cache versi lama
self.addEventListener("activate", (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(
        keys
          .filter((k) => k !== "toko-kita-v1")
          .map((k) => caches.delete(k))
      )
    )
  );
});
 
// FETCH — putuskan: cache, jaringan, atau keduanya
self.addEventListener("fetch", (event) => {
  event.respondWith(handleFetch(event.request));
});

Mengapa service worker butuh HTTPS? Karena ia bisa mencegat semua request — browser tidak mengizinkan proxy ini di halaman non-secure.

Note

Perhatikan versi cache (toko-kita-v1). Saat aset berubah, ganti nama versi — service worker lalu membersihkan yang lama saat activate. Inilah mekanisme utama menghindari pengguna "terkunci" di versi lama aplikasi.

Strategi Caching

Empat pola umum — pilih sesuai jenis konten:

StrategiAlurCocok untuk
Cache-firstCache dulu, fallback jaringanAset statis (CSS, gambar, ikon)
Network-firstJaringan dulu, fallback cacheAPI & halaman yang butuh data segar
Stale-while-revalidateCache dulu, perbarui di latarKonten yang boleh sedikit basi
Network-onlyJangan pernah cacheMutasi & data sensitif (checkout)
Network-first untuk halaman
async function handleFetch(request: Request): Promise<Response> {
  const cache = await caches.open("toko-kita-v1");
 
  try {
    const res = await fetch(request);
    if (res.ok) cache.put(request, res.clone());
    return res;
  } catch {
    return (await cache.match(request)) || caches.match("/offline.html");
  }
}

Pola ini membuat halaman selalu segar saat online, dan tetap muncul saat offline. Perhatikan fallback terakhir: halaman offline.html yang ramah (bukan error browser).

Installability dan Manifest

Manifest membuat aplikasi "installable" — dengan ikon, nama, dan mode tampilan:

manifest.json
{
  "name": "TokoKita",
  "short_name": "TokoKita",
  "description": "Toko online sederhana",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#b45309",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
  ]
}
Registrasi service worker
if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker.register("/sw.js");
  });
}

Browser mengizinkan install prompt saat: HTTPS, manifest valid, ikon ada, dan ada service worker dengan fetch handler.

Praktik: PWA TokoKita

Di Next.js, pendekatan praktis 2026:

  • next-pwa — membungkus setup service worker otomatis (Workbox).
  • next/offline (Next.js 15+) — eksperimental, integrasi bawaan.
  • Manual — tulis sw.ts sendiri untuk kontrol penuh (belajar paling banyak).
Prioritas caching TokoKita
Statis (/_next/static, gambar, font) → cache-first
Halaman publik (/products)          → stale-while-revalidate
API produk                          → network-first
Checkout & auth                     → network-only (jangan cache!)

Common Pitfalls

KesalahanDampakPerbaikan
Cache semua request termasuk mutasiData aneh/duplikatNetwork-only untuk POST/auth
Cache versi tidak diaturPengguna stuck versi lamaVersioning cache + cleanup
Service worker tanpa fallback offlineError browser yang menakutkanHalaman offline.html yang ramah
Cache API yang salahHarga/stok basiTTL atau network-first
Registrasi di halaman non-HTTPSTidak pernah jalanHTTPS wajib

Penutup

Inti yang harus dibawa pulang:

  • PWA = reliable (offline), installable (manifest), engaging — web app setara native.
  • Service worker adalah proxy jaringan: install/activate/fetch dengan versioning cache.
  • Pilih strategi caching per konten: statis cache-first, halaman stale-while-revalidate, mutasi network-only.
  • Manifest + ikon + HTTPS + SW = syarat installability.

Di episode 23 selanjutnya kita membuat data bisa dibaca: data visualization — charts dengan Recharts/D3, dashboard interaktif, dan performa rendering data TokoKita. Sampai jumpa di episode 23!

Belajar Frontend - PWA & Offline First | Belajar Frontend