Tutorial: Mengubah Website Statis Sederhana Menjadi Progressive Web App (PWA)
Pernahkah Anda menginginkan website Anda bisa diakses bahkan saat tidak ada koneksi internet? Atau mungkin Anda ingin pengguna bisa “menginstal” website Anda ke layar utama perangkat mereka layaknya aplikasi native? Selamat datang di dunia Progressive Web Apps (PWA)!
Dalam tutorial ini, kita akan mengubah sebuah website statis sederhana (yang dibangun dengan HTML, CSS, dan JavaScript) menjadi PWA yang fungsional.
1. Pendahuluan
Apa itu PWA (Progressive Web App)?
PWA adalah aplikasi web yang menggunakan teknologi web modern untuk memberikan pengalaman pengguna yang mirip dengan aplikasi native (aplikasi yang diinstal dari app store). PWA dirancang untuk menjadi:
- Progressive: Bekerja untuk setiap pengguna, terlepas dari pilihan browser, karena dibangun dengan peningkatan progresif sebagai inti.
- Responsive: Cocok untuk berbagai ukuran layar: desktop, tablet, dan mobile.
- App-like: Terasa seperti aplikasi native dengan navigasi dan interaksi ala aplikasi.
- Connectivity-independent: Dapat bekerja secara offline atau pada jaringan berkualitas rendah berkat Service Worker.
- Installable: Memungkinkan pengguna untuk menambahkannya ke layar utama (home screen) mereka tanpa perlu melalui app store.
- Fresh: Selalu up-to-date berkat proses update Service Worker.
- Safe: Disajikan melalui HTTPS untuk mencegah snooping dan memastikan konten tidak dirusak.
- Discoverable: Dapat diidentifikasi sebagai “aplikasi” berkat manifest W3C dan arsitektur registrasi Service Worker yang memungkinkan mesin pencari untuk menemukannya.
- Re-engageable: Memudahkan re-engagement melalui fitur seperti push notification.
- Linkable: Mudah dibagikan melalui URL dan tidak memerlukan instalasi yang rumit.
Manfaat PWA
- Akses Offline: Pengguna tetap bisa mengakses konten dasar meskipun tidak ada koneksi internet.
- Installable: Pengalaman pengguna yang lebih imersif dan mudah diakses dari home screen.
- Cepat dan Ringan: Dengan caching yang cerdas, PWA bisa dimuat sangat cepat.
- Jangkauan Luas: Dibangun dengan teknologi web, bisa diakses di berbagai platform dan browser.
- Engagement Lebih Tinggi: Fitur seperti push notification (lebih advance) bisa meningkatkan interaksi pengguna.
Target Akhir Tutorial
Kita akan mengambil sebuah website statis sederhana dan menambahkan dua komponen inti PWA: Web App Manifest dan Service Worker, sehingga website tersebut bisa di-install dan memiliki kemampuan dasar untuk berjalan offline.
2. Struktur Awal Proyek
Kita akan memulai dengan struktur proyek yang minimalis. Buat sebuah folder utama, misalnya pwa-sederhana/
, lalu di dalamnya buat file dan folder berikut:
/pwa-sederhana/
├── index.html // Halaman utama aplikasi kita
├── style.css // Untuk styling dasar
├── app.js // Untuk mendaftarkan Service Worker dan logika JS lain (jika ada)
├── manifest.json // File metadata PWA
├── service-worker.js // Otak caching dan fungsionalitas offline
└── icons/ // Folder untuk menyimpan ikon aplikasi
├── icon-192.png // Ikon ukuran 192x192 piksel
└── icon-512.png // Ikon ukuran 512x512 piksel
Penjelasan Singkat Tiap File:
index.html
: Halaman utama aplikasi web kita.style.css
: Berisi aturan CSS untuk tampilan.app.js
: Skrip JavaScript utama, salah satunya untuk mendaftarkan Service Worker.manifest.json
: File JSON yang memberikan informasi tentang aplikasi Anda (nama, ikon, warna tema, dll.) kepada browser.service-worker.js
: Skrip JavaScript yang berjalan di latar belakang, terpisah dari halaman web, dan memungkinkan fitur seperti caching, kemampuan offline, dan push notification.icons/
: Folder ini akan berisi ikon-ikon aplikasi yang akan digunakan saat PWA di-install ke home screen atau untuk splash screen. Anda perlu membuat atau mengunduh dua ikon dengan ukuran tersebut (misalnya, dalam format PNG).
Persiapan Ikon:
Anda bisa membuat ikon sendiri atau menggunakan generator ikon PWA online. Pastikan Anda memiliki setidaknya icon-192.png
dan icon-512.png
di dalam folder icons/
.
3. Membuat Halaman HTML Sederhana (index.html
)
Kita akan membuat halaman HTML yang sangat sederhana sebagai dasar PWA kita.
Buat atau modifikasi file index.html
:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Link ke Manifest Web App -->
<link rel="manifest" href="manifest.json">
<!-- Meta tag untuk warna tema browser (Android Chrome) -->
<meta name="theme-color" content="#2196f3">
<link rel="stylesheet" href="style.css">
<title>PWA Sederhana Saya</title>
<!-- (Opsional) Apple-specific meta tags untuk pengalaman PWA di iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="PWA Saya">
<link rel="apple-touch-icon" href="icons/icon-192.png"> <!-- Pilih ikon yang sesuai untuk iOS -->
</head>
<body>
<header>
<h1>Selamat Datang di PWA Sederhana!</h1>
</header>
<main>
<p>Website ini adalah contoh Progressive Web App.</p>
<p>Setelah Service Worker aktif, konten ini bisa diakses secara offline dan aplikasi ini bisa di-install ke perangkat Anda.</p>
<button id="updateButton">Cek Pembaruan Manual (SW)</button>
</main>
<footer>
<p>© <span id="currentYear"></span> PWA Keren</p>
</footer>
<script src="app.js"></script>
</body>
</html>
Perubahan Penting:
<link rel="manifest" href="manifest.json">
: Ini memberitahu browser di mana menemukan file manifest aplikasi Anda.<meta name="theme-color" content="#2196f3">
: Mengatur warna tema untuk address bar browser di perangkat mobile (terutama Android). Nilai ini sebaiknya sama dengantheme_color
dimanifest.json
.- Meta Tags Apple (Opsional): Ditambahkan untuk meningkatkan pengalaman saat PWA “ditambahkan ke Home Screen” di perangkat iOS.
4. Membuat Manifest Web App (manifest.json
)
File manifest.json
adalah file JSON sederhana yang memberikan informasi tentang PWA Anda kepada browser. Ini memungkinkan website Anda di-install ke home screen perangkat pengguna.
Buat file manifest.json
di root proyek Anda:
{
"name": "PWA Sederhana Saya",
"short_name": "PWA Saya",
"description": "Contoh aplikasi PWA sederhana yang bisa diakses offline dan di-install.",
"start_url": "./index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2196f3",
"orientation": "portrait-primary",
"scope": "/",
"icons": [
{
"src": "icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
Penjelasan Properti Manifest:
name
: Nama lengkap aplikasi Anda, akan muncul saat instalasi atau di splash screen.short_name
: Nama pendek yang akan muncul di bawah ikon aplikasi di home screen.description
: Deskripsi singkat tentang aplikasi Anda.start_url
: URL yang akan dibuka saat pengguna meluncurkan PWA dari home screen. Biasanya halaman utama (index.html
)../
memastikan path relatif terhadap lokasi manifest.display
: Mengontrol bagaimana PWA ditampilkan.standalone
: Aplikasi terasa seperti aplikasi native, tanpa UI browser (address bar, dll.). Pilihan umum untuk PWA.fullscreen
: Mengambil seluruh layar.minimal-ui
: Mirip standalone tapi dengan beberapa kontrol navigasi browser minimal.browser
: Membuka di tab browser biasa.
background_color
: Warna latar belakang yang ditampilkan saat PWA dimuat (splash screen).theme_color
: Warna tema utama aplikasi, sering digunakan untuk mewarnai status bar atau UI browser.orientation
: Orientasi layar yang diinginkan (misalnya,portrait-primary
,landscape
).scope
: Menentukan cakupan navigasi PWA. URL di luar scope ini akan dibuka di browser biasa./
berarti semua URL di bawah domain/root PWA.icons
: Array objek yang mendefinisikan ikon-ikon aplikasi untuk berbagai ukuran.src
: Path ke file ikon.sizes
: Ukuran ikon (misalnya, “192x192”).type
: Tipe MIME gambar (misalnya, “image/png”).purpose
: Menjelaskan tujuan ikon.any maskable
penting agar ikon Anda terlihat baik di berbagai bentuk ikon (bundar, kotak, dll.) yang digunakan oleh sistem operasi yang berbeda. Ikon “maskable” didesain dengan zona aman.
Pastikan path ke ikon (icons/icon-192.png
, dll.) sudah benar.
5. 🔧 Membuat Service Worker
Service Worker (SW) adalah skrip JavaScript yang berjalan di latar belakang, terpisah dari halaman web Anda. Ini adalah teknologi inti di balik kemampuan offline dan caching PWA.
5.1. Apa itu Service Worker?
- Proksi Jaringan: SW bisa mencegat (intercept) permintaan jaringan yang dibuat oleh halaman Anda (misalnya, permintaan untuk file CSS, JS, gambar, atau data API).
- Caching: SW bisa menyimpan aset (file) ke dalam Cache Storage browser. Saat halaman meminta aset tersebut lagi, SW bisa menyajikannya dari cache, bahkan saat offline.
- Fitur Lanjutan: SW juga merupakan dasar untuk fitur seperti push notification dan background sync.
- Berjalan di Thread Terpisah: Tidak memblokir thread utama browser, sehingga tidak memengaruhi performa UI.
- Harus HTTPS: Untuk alasan keamanan, SW hanya bisa didaftarkan dan berjalan di halaman yang disajikan melalui HTTPS (kecuali untuk
localhost
selama pengembangan).
5.2. Contoh Service Worker Dasar (service-worker.js
)
Buat file service-worker.js
di root proyek Anda:
// service-worker.js
// Nama cache dan versi. Ubah versi jika Anda membuat perubahan pada file yang di-cache.
const CACHE_NAME = "pwa-sederhana-cache-v1";
// Daftar file yang ingin di-cache saat instalasi Service Worker.
// Pastikan semua path sudah benar relatif terhadap root domain/folder.
const urlsToCache = [
"/", // Cache halaman utama (index.html di root)
"index.html",
"style.css",
"app.js",
"manifest.json", // Manifest juga penting untuk pengalaman offline
"icons/icon-192.png",
"icons/icon-512.png"
// Tambahkan aset lain yang penting untuk pengalaman offline dasar
// Misalnya: "images/logo.png", "offline.html" (halaman fallback)
];
// Event 'install': Terjadi saat Service Worker pertama kali diinstal atau diupdate.
self.addEventListener("install", event => {
console.log("Service Worker: Menginstall...");
// event.waitUntil() memastikan Service Worker tidak dianggap terinstal
// sampai kode di dalamnya selesai dieksekusi.
event.waitUntil(
caches.open(CACHE_NAME) // Buka (atau buat) cache dengan nama CACHE_NAME
.then(cache => {
console.log("Service Worker: Cache dibuka, menambahkan file ke cache...");
return cache.addAll(urlsToCache); // Tambahkan semua URL di urlsToCache ke cache
})
.then(() => {
console.log("Service Worker: Semua file berhasil dicache.");
// (Opsional) Melewati waiting phase agar SW baru langsung aktif
// return self.skipWaiting();
})
.catch(error => {
console.error("Service Worker: Gagal melakukan pre-caching saat instalasi.", error);
})
);
});
// Event 'activate': Terjadi setelah Service Worker terinstal dan siap mengontrol halaman.
// Berguna untuk membersihkan cache lama.
self.addEventListener("activate", event => {
console.log("Service Worker: Mengaktifkan...");
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
// Hapus cache lama yang tidak sesuai dengan CACHE_NAME saat ini
if (cacheName !== CACHE_NAME) {
console.log("Service Worker: Menghapus cache lama:", cacheName);
return caches.delete(cacheName);
}
})
);
})
// (Opsional) Membuat SW baru langsung mengontrol klien yang terbuka
// .then(() => self.clients.claim())
);
});
// Event 'fetch': Terjadi setiap kali halaman yang dikontrol oleh SW membuat permintaan jaringan (misalnya, untuk CSS, JS, gambar, API).
self.addEventListener("fetch", event => {
// console.log("Service Worker: Mengambil request untuk:", event.request.url);
event.respondWith(
caches.match(event.request) // Coba cari respons untuk request ini di cache
.then(cachedResponse => {
// Jika ditemukan di cache, kembalikan respons dari cache
if (cachedResponse) {
// console.log("Service Worker: Menyajikan dari cache:", event.request.url);
return cachedResponse;
}
// Jika tidak ditemukan di cache, lanjutkan dengan permintaan jaringan asli
// console.log("Service Worker: Tidak ada di cache, mengambil dari jaringan:", event.request.url);
return fetch(event.request)
.then(networkResponse => {
// (Opsional) Cache respons baru jika Anda ingin update cache secara dinamis
// Ini strategi "Network falling back to cache", lalu "Cache then network" jika ditambah caching di sini.
// Pastikan Anda tidak meng-cache respons error atau respons dari API yang tidak seharusnya di-cache.
// if (networkResponse && networkResponse.status === 200 && networkResponse.type === 'basic') {
// const responseToCache = networkResponse.clone();
// caches.open(CACHE_NAME).then(cache => {
// cache.put(event.request, responseToCache);
// });
// }
return networkResponse;
})
.catch(error => {
console.error("Service Worker: Gagal mengambil dari jaringan maupun cache.", error);
// (Opsional) Kembalikan halaman fallback offline jika request gagal total
// if (event.request.mode === 'navigate') { // Hanya untuk navigasi halaman
// return caches.match('offline.html');
// }
});
})
);
});
Penjelasan Service Worker:
CACHE_NAME
: Nama cache. Penting untuk diubah versinya (v1
,v2
, dst.) saat Anda memperbarui file yang di-cache agar SW mengambil versi baru.urlsToCache
: Daftar file yang akan di-cache saat SW diinstal. Pastikan path-nya benar relatif terhadap root domain (karena SW berjalan di root). Jikaindex.html
ada di root, maka/
atauindex.html
atau./index.html
bisa digunakan. Untuk konsistensi,/
untuk root dan path lengkap untuk file lain.- Event
install
:- Dipanggil saat SW pertama kali didaftarkan atau saat ada versi baru SW.
event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache)))
: Membuka cache dan menambahkan semua file diurlsToCache
ke dalamnya.waitUntil
menunda penyelesaian instalasi sampai proses caching selesai.self.skipWaiting()
(opsional): Jika ada SW lama yang aktif, SW baru akan masuk ke state “waiting” sampai SW lama tidak lagi mengontrol klien.skipWaiting()
memaksa SW baru untuk aktif lebih cepat.
- Event
activate
:- Dipanggil setelah SW terinstal dan SW lama (jika ada) sudah tidak aktif.
- Digunakan untuk membersihkan cache lama yang tidak lagi dibutuhkan. Ini penting agar tidak memenuhi penyimpanan pengguna dengan file usang.
self.clients.claim()
(opsional): Memungkinkan SW yang baru diaktifkan untuk segera mengontrol semua klien (tab browser) yang terbuka yang berada dalam scope-nya, tanpa perlu menunggu refresh halaman.
- Event
fetch
:- Ini adalah inti dari kemampuan offline. Setiap permintaan jaringan dari halaman akan melewati event ini.
event.respondWith()
: Mengambil alih respons default browser.caches.match(event.request)
: Mencoba menemukan respons yang cocok untuk permintaan saat ini di dalam cache.- Strategi Cache: Cache First, falling back to Network: Jika ada di cache, sajikan dari cache. Jika tidak, ambil dari jaringan.
- Caching Dinamis (Opsional): Anda bisa menambahkan logika untuk menyimpan respons dari jaringan ke cache setelah berhasil diambil, sehingga permintaan berikutnya untuk resource yang sama bisa lebih cepat atau bekerja offline.
- Halaman Fallback Offline (Opsional): Jika permintaan jaringan gagal dan tidak ada di cache, Anda bisa menampilkan halaman
offline.html
kustom.
5.3. Register Service Worker (app.js
)
Service Worker tidak akan aktif sampai kita mendaftarkannya dari halaman web kita menggunakan JavaScript.
Buat atau modifikasi file app.js
:
// app.js
// Update tahun di footer (jika belum ada di file lain atau ingin sentralisasi)
const currentYearElement = document.getElementById('currentYear');
if (currentYearElement) {
currentYearElement.textContent = new Date().getFullYear();
}
// Registrasi Service Worker
if ("serviceWorker" in navigator) { // Cek apakah browser mendukung Service Worker
window.addEventListener("load", () => { // Daftarkan setelah halaman selesai dimuat
navigator.serviceWorker
.register("/service-worker.js", { scope: "/" }) // Path ke file SW dan scope-nya
.then(registration => {
console.log("Service Worker berhasil terdaftar dengan scope:", registration.scope);
// (Opsional) Logika untuk menangani update SW
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker) {
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed' && navigator.serviceWorker.controller) {
// SW baru telah terinstal.
// Anda bisa memberi tahu pengguna bahwa ada update dan mereka perlu me-refresh.
console.log('Service Worker baru telah terinstal. Konten baru tersedia setelah refresh.');
// Contoh: tampilkan notifikasi update
// if (confirm('Versi baru aplikasi tersedia. Muat ulang sekarang?')) {
// window.location.reload();
// }
}
};
}
};
})
.catch(error => {
console.error("Registrasi Service Worker gagal:", error);
});
});
// (Opsional) Tombol untuk cek pembaruan SW secara manual
const updateButton = document.getElementById('updateButton');
if (updateButton) {
updateButton.addEventListener('click', () => {
navigator.serviceWorker.getRegistration().then(reg => {
if (reg) {
reg.update().then(() => {
console.log('Pengecekan pembaruan Service Worker dimulai.');
// Notifikasi atau logika lain setelah pembaruan dicoba
});
}
});
});
}
} else {
console.log("Service Worker tidak didukung oleh browser ini.");
}
Penjelasan Registrasi SW:
"serviceWorker" in navigator
: Pengecekan fitur untuk memastikan browser mendukung SW.window.addEventListener("load", ...)
: Mendaftarkan SW setelah semua aset halaman utama (HTML, CSS, JS awal) selesai dimuat. Ini praktik baik agar tidak mengganggu pemuatan awal halaman.navigator.serviceWorker.register("/service-worker.js", { scope: "/" })
:- Argumen pertama adalah path ke file
service-worker.js
Anda. Path ini relatif terhadap origin (domain), bukan fileapp.js
. Jadi, jikaservice-worker.js
ada di root, path-nya adalah/service-worker.js
. { scope: "/" }
(opsional): Menentukan direktori mana yang akan dikontrol oleh SW./
berarti SW akan mengontrol semua halaman di root domain Anda. Defaultnya adalah direktori tempat file SW berada. Mengaturnya ke/
adalah praktik umum.
- Argumen pertama adalah path ke file
- .then(): Jika registrasi berhasil.
- .catch(): Jika registrasi gagal.
- Logika Update SW (Opsional): Bagian
registration.onupdatefound
adalah contoh bagaimana Anda bisa mendeteksi jika ada versi baru SW yang terinstal dan memberi tahu pengguna. Ini adalah UX yang baik. - Tombol Cek Pembaruan Manual (Opsional): Memberikan cara bagi pengguna untuk memicu pengecekan update SW.
6. Pengujian Instalasi PWA
Setelah semua file dibuat, saatnya menguji!
-
Jalankan Server Lokal: Sangat penting! PWA dan Service Worker memerlukan lingkungan HTTPS, tetapi browser mengizinkan
localhost
untuk pengembangan. Gunakan salah satu metode dari tutorial sebelumnya:npx serve .
python -m http.server
- Live Server di VS Code.
Buka aplikasi Anda di browser melalui URL server lokal (misalnya,
http://localhost:3000
).
-
Buka Developer Tools: Di Chrome atau Edge, tekan F12 atau klik kanan > Inspect.
-
Tab “Application” (atau “Aplikasi”):
- Manifest: Di panel kiri, klik “Manifest”. Anda akan melihat informasi dari
manifest.json
Anda. Jika ada error, akan ditampilkan di sini. Pastikan semua link ikon benar. - Service Workers: Klik “Service Workers”. Anda akan melihat
service-worker.js
Anda terdaftar dan statusnya (misalnya, “activated and is running”).- Centang “Update on reload” selama pengembangan agar setiap refresh mengambil SW terbaru.
- Anda bisa menggunakan tombol “Unregister” untuk menghapus SW, atau “Update” untuk memaksa update.
- Cache Storage: Di bawah “Storage”, klik “Cache Storage”. Anda akan melihat cache dengan nama
pwa-sederhana-cache-v1
(atau nama yang Anda definisikan). Klik untuk melihat file-file yang sudah di-cache.
- Manifest: Di panel kiri, klik “Manifest”. Anda akan melihat informasi dari
-
Simulasikan Offline:
- Di tab “Service Workers” (atau tab “Network”), ada checkbox “Offline”. Centang ini.
- Sekarang coba refresh halaman (
Ctrl+R
atauCmd+R
). Jika SW dan caching bekerja dengan benar, halaman Anda seharusnya tetap termuat dari cache! - Coba buka aset lain yang sudah di-cache (misalnya, buka
style.css
langsung di browser).
-
Klik Tombol Install:
- Setelah beberapa saat berinteraksi dengan situs Anda (dan jika semua kriteria PWA terpenuhi: HTTPS/localhost, manifest, SW), browser (terutama Chrome/Edge di desktop dan Android) akan menampilkan ikon “install” di address bar atau menu.
- Klik ikon tersebut. Anda akan melihat prompt untuk menginstal aplikasi.
- Setelah diinstal, PWA akan muncul sebagai ikon di desktop Anda (Windows/Mac/Linux) atau di app drawer/home screen (Android). Di iOS, Anda perlu menggunakan “Add to Home Screen” dari menu Share di Safari.
- Luncurkan PWA dari ikon tersebut. Seharusnya terbuka dalam jendela sendiri (
display: standalone
).
7. Tips Debugging dan Pengembangan
- Gunakan Lighthouse di DevTools:
- Buka tab “Lighthouse”.
- Pilih kategori “Progressive Web App” dan jalankan audit. Lighthouse akan memberikan skor dan saran untuk meningkatkan PWA Anda.
- DevTools Tab “Application”: Ini adalah teman terbaik Anda untuk debugging PWA. Periksa status SW, isi cache, dan error manifest.
- Clear Cache dan Unregister SW Saat Debugging: Kadang-kadang SW yang lama atau cache yang salah bisa menyebabkan masalah. Gunakan DevTools untuk membersihkannya.
- Application > Storage > Clear site data.
- Application > Service Workers > Unregister.
- Update Versi Cache (
CACHE_NAME
): Setiap kali Anda membuat perubahan pada file yang di-cache (misalnya,style.css
atauapp.js
), Anda harus mengubah namaCACHE_NAME
diservice-worker.js
(misalnya, dariv1
kev2
). Ini akan memicu eventinstall
danactivate
pada SW, sehingga cache lama dihapus dan cache baru dengan file yang diperbarui dibuat. - Hard Refresh: Tekan
Ctrl+Shift+R
(atauCmd+Shift+R
di Mac) untuk melakukan hard refresh yang biasanya melewati cache browser (tapi mungkin tidak selalu cache Service Worker). Kombinasikan dengan “Update on reload” di DevTools. - Konsol Browser: Perhatikan pesan log dari SW dan
app.js
.
8. Bonus: Fitur Lanjutan
- Offline Fallback Page:
Buat halaman
offline.html
sederhana. Tambahkan keurlsToCache
di SW. Kemudian, di eventfetch
, jikafetch(event.request)
gagal (masuk ke.catch()
), Anda bisa merespons dengan konten darioffline.html
:// Di dalam event 'fetch', bagian .catch() .catch(error => { console.error("Service Worker: Gagal mengambil dari jaringan maupun cache.", error); // Jika permintaan adalah untuk navigasi halaman if (event.request.mode === 'navigate') { return caches.match('offline.html'); // Pastikan offline.html sudah di-cache } });
- Strategi Caching Berbeda: Yang kita gunakan adalah “Cache First, falling back to Network”. Ada strategi lain seperti “Network First, falling back to Cache”, “Stale-While-Revalidate”, dll. Library seperti Workbox memudahkan implementasi strategi ini.
- Background Sync: Memungkinkan aplikasi untuk menunda aksi (misalnya, mengirim form) sampai koneksi internet stabil. (Lebih advance).
- Push Notification: Mengirim notifikasi ke pengguna meskipun mereka tidak sedang membuka PWA. (Memerlukan backend dan izin pengguna).
9. Catatan Hosting
- HTTPS WAJIB: Untuk PWA berfungsi di lingkungan produksi (non-localhost), situs Anda harus disajikan melalui HTTPS. Ini adalah persyaratan keamanan untuk Service Worker. Banyak penyedia hosting modern menawarkan sertifikat SSL gratis (misalnya, via Let’s Encrypt).
- Pengujian Lokal: Seperti yang sudah dibahas, gunakan server lokal sederhana (
npx serve .
,python -m http.server
, Live Server VS Code) agarfetch()
dan registrasi SW berjalan dengan benar.
10. Penutup
Selamat! Anda telah berhasil mengubah website statis sederhana menjadi Progressive Web App. Website Anda sekarang memiliki kemampuan untuk:
- Diakses saat offline (untuk aset yang sudah di-cache).
- Di-install ke perangkat pengguna seperti aplikasi native.
- Dimuat lebih cepat pada kunjungan berikutnya berkat caching Service Worker.
Ini adalah fondasi yang bagus dan sangat cocok untuk portofolio, blog statis, dokumentasi, atau aplikasi web sederhana lainnya yang ingin Anda berikan pengalaman pengguna yang lebih baik.
Dorongan untuk Mengembangkan Lebih Jauh:
- Gunakan Workbox: Workbox adalah library dari Google yang menyederhanakan banyak aspek pembuatan Service Worker, terutama untuk caching dan strategi caching yang kompleks.
- Implementasi Page Routing Offline: Untuk Single Page Applications (SPA), Anda perlu strategi routing yang bekerja offline.
- Eksplorasi Fitur PWA Lanjutan: Seperti background sync, push notification, atau periodic background sync.
- Audit dengan Lighthouse Secara Berkala: Terus pantau dan tingkatkan skor PWA Anda.
11. Referensi Tambahan
- MDN Web Docs - Progressive Web Apps: https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps
- Google Developers - Your First Progressive Web App: https://web.dev/progressive-web-apps/ (Cari codelab atau artikel terbaru mereka)
- Web.dev - PWA Checklist: https://web.dev/pwa-checklist/
- Can I use… Service Workers: https://caniuse.com/serviceworkers (untuk mengecek dukungan browser)
Semoga tutorial ini bermanfaat dan membuka pintu bagi Anda untuk menjelajahi dunia PWA lebih dalam!