Salah satu aspek utama Progressive Web App adalah keandalannya; aplikasi ini dapat memuat aset dengan cepat, membuat pengguna tetap berinteraksi dan memberikan masukan dengan segera, bahkan dalam kondisi jaringan yang buruk. Bagaimana mungkin? Berkat peristiwa fetch
pekerja layanan.
Peristiwa pengambilan
Peristiwa fetch
memungkinkan kita mencegat setiap permintaan jaringan yang dibuat oleh PWA dalam cakupan pekerja layanan, baik untuk permintaan lintas origin maupun origin yang sama. Selain permintaan navigasi dan aset, pengambilan data dari pekerja layanan yang diinstal memungkinkan kunjungan halaman setelah pemuatan pertama situs dirender tanpa panggilan jaringan.
Handler fetch
menerima semua permintaan dari aplikasi, termasuk URL dan header HTTP, serta memungkinkan developer aplikasi memutuskan cara memprosesnya.
Service worker Anda dapat meneruskan permintaan ke jaringan, merespons dengan respons yang di-cache sebelumnya, atau membuat respons baru. Anda yang menentukan. Berikut adalah contoh sederhana:
self.addEventListener("fetch", event => { console.log(`URL requested: ${event.request.url}`); });
Merespons permintaan
Saat permintaan masuk ke pekerja layanan, ada dua hal yang dapat Anda lakukan; Anda dapat mengabaikannya, yang memungkinkannya masuk ke jaringan, atau Anda dapat meresponsnya. Merespons permintaan dari dalam pekerja layanan adalah cara Anda dapat memilih apa yang akan dikembalikan ke PWA Anda dan bagaimana cara mengembalikannya, bahkan saat pengguna offline.
Untuk merespons permintaan masuk, panggil event.respondWith()
dari dalam pengendali peristiwa fetch
, seperti ini:
// fetch event handler in your service worker file self.addEventListener("fetch", event => { const response = .... // a response or a Promise of response event.respondWith(response); });
Anda harus memanggil respondWith()
secara sinkron dan menampilkan objek Response. Namun, Anda tidak dapat memanggil respondWith()
setelah pengendali peristiwa pengambilan selesai, seperti dalam panggilan asinkron. Jika Anda perlu menunggu respons lengkap, Anda dapat meneruskan Promise ke respondWith()
yang diselesaikan dengan Respons.
Membuat respons
Berkat Fetch API, Anda dapat membuat respons HTTP dalam kode JavaScript, dan respons tersebut dapat di-cache menggunakan Cache Storage API dan ditampilkan seolah-olah berasal dari server web.
Untuk membuat respons, buat objek Response
baru, tetapkan isi dan opsinya seperti status dan header:
const simpleResponse = new Response("Body of the HTTP response"); const options = { status: 200, headers: { 'Content-type': 'text/html' } }; const htmlResponse = new Response("<b>HTML</b> content", options)
Merespons dari cache
Sekarang setelah Anda mengetahui cara menyajikan respons HTTP dari pekerja layanan, saatnya menggunakan antarmuka Caching Storage untuk menyimpan aset di perangkat.
Anda dapat menggunakan API penyimpanan cache untuk memeriksa apakah permintaan yang diterima dari PWA tersedia di cache, dan jika tersedia, merespons respondWith()
dengan permintaan tersebut. Untuk melakukannya, Anda harus menelusuri dalam cache terlebih dahulu. Fungsi match()
, yang tersedia di antarmuka caches
tingkat teratas, menelusuri semua toko di asal Anda, atau pada satu objek cache terbuka.
Fungsi match()
menerima permintaan HTTP atau URL sebagai argumen dan menampilkan promise yang di-resolve dengan Response yang terkait dengan kunci yang sesuai.
// Global search on all caches in the current origin caches.match(urlOrRequest).then(response => { console.log(response ? response : "It's not in the cache"); }); // Cache-specific search caches.open("pwa-assets").then(cache => { cache.match(urlOrRequest).then(response => { console.log(response ? response : "It's not in the cache"); }); });
Strategi penyimpanan dalam cache
Menayangkan file hanya dari cache browser tidak sesuai untuk setiap kasus penggunaan. Misalnya, pengguna atau browser dapat menghapus cache. Itulah sebabnya Anda harus menentukan strategi sendiri untuk mengirimkan aset untuk PWA Anda. Anda tidak dibatasi pada satu strategi penyimpanan dalam cache. Anda dapat menentukan yang berbeda untuk pola URL yang berbeda. Misalnya, Anda dapat memiliki satu strategi untuk aset UI minimum, satu lagi untuk panggilan API, dan yang ketiga untuk URL gambar dan data. Untuk melakukannya, baca event.request.url
di ServiceWorkerGlobalScope.onfetch
dan parsing melalui ekspresi reguler atau Pola URL. (Pada saat penulisan, Pola URL tidak didukung di semua platform).
Strategi yang paling umum adalah:
- Cache First
- Menelusuri respons yang di-cache terlebih dahulu dan melakukan penggantian ke jaringan jika tidak ditemukan.
- Jaringan Terlebih Dahulu
- Meminta respons dari jaringan terlebih dahulu dan jika tidak ada yang ditampilkan, memeriksa respons dalam cache.
- Tidak Relevan Saat Divalidasi Ulang
- Menyajikan respons dari cache, sambil meminta versi terbaru di latar belakang dan menyimpannya ke cache untuk waktu berikutnya saat aset diminta.
- Khusus Jaringan
- Selalu membalas dengan respons dari jaringan atau error. Cache tidak pernah diperiksa.
- Khusus Cache
- Selalu membalas dengan respons dari cache atau menampilkan error. Jaringan tidak akan pernah dikonsultasikan. Aset yang akan ditayangkan menggunakan strategi ini harus ditambahkan ke cache sebelum diminta.
Cache terlebih dahulu
Dengan menggunakan strategi ini, pekerja layanan akan mencari permintaan yang cocok dalam cache dan menampilkan Respons yang sesuai jika di-cache. Jika tidak, respons akan diambil dari jaringan (secara opsional, memperbarui cache untuk panggilan di masa mendatang). Jika tidak ada respons cache maupun respons jaringan, permintaan akan error. Karena penayangan aset tanpa membuka jaringan cenderung lebih cepat, strategi ini memprioritaskan performa daripada keaktualan.
self.addEventListener("fetch", event => { event.respondWith( caches.match(event.request) .then(cachedResponse => { // It can update the cache to serve updated content on the next request return cachedResponse || fetch(event.request); } ) ) });
Network first
Strategi ini adalah kebalikan dari strategi Cache First; strategi ini memeriksa apakah permintaan dapat dipenuhi dari jaringan dan, jika tidak dapat, mencoba mengambilnya dari cache. Seperti cache terlebih dahulu. Jika tidak ada respons jaringan maupun respons cache, permintaan akan error. Mendapatkan respons dari jaringan biasanya lebih lambat daripada mendapatkannya dari cache. Strategi ini memprioritaskan konten yang diperbarui, bukan performa.
self.addEventListener("fetch", event => { event.respondWith( fetch(event.request) .catch(error => { return caches.match(event.request) ; }) ); });
Tidak relevan saat divalidasi ulang
Strategi basi saat divalidasi ulang akan segera menampilkan respons yang di-cache, lalu memeriksa update di jaringan, dan mengganti respons yang di-cache jika ditemukan update. Strategi ini selalu membuat permintaan jaringan, karena meskipun resource yang di-cache ditemukan, strategi ini akan mencoba memperbarui apa yang ada di cache dengan apa yang diterima dari jaringan, untuk menggunakan versi yang diperbarui dalam permintaan berikutnya. Oleh karena itu, strategi ini memberikan cara bagi Anda untuk mendapatkan manfaat dari strategi penyajian cepat cache terlebih dahulu dan memperbarui cache di latar belakang.
self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(cachedResponse => { const networkFetch = fetch(event.request).then(response => { // update the cache with a clone of the network response const responseClone = response.clone() caches.open(url.searchParams.get('name')).then(cache => { cache.put(event.request, responseClone) }) return response }).catch(function (reason) { console.error('ServiceWorker fetch failed: ', reason) }) // prioritize cached response over network return cachedResponse || networkFetch } ) ) })
Khusus jaringan
Strategi hanya jaringan serupa dengan perilaku browser tanpa pekerja layanan atau Cache Storage API. Permintaan hanya akan menampilkan resource jika resource tersebut dapat diambil dari jaringan. Hal ini sering kali berguna untuk resource seperti permintaan API khusus online.
Hanya cache
Strategi hanya cache memastikan bahwa permintaan tidak pernah masuk ke jaringan; semua permintaan masuk direspons dengan item cache yang telah diisi sebelumnya. Kode berikut menggunakan pengendali peristiwa fetch
dengan metode match
penyimpanan cache untuk merespons hanya cache:
self.addEventListener("fetch", event => { event.respondWith(caches.match(event.request)); });
Strategi kustom
Meskipun strategi caching di atas umum digunakan, Anda bertanggung jawab atas pekerja layanan dan cara permintaan ditangani. Jika tidak ada yang sesuai dengan kebutuhan Anda, buat sendiri.
Misalnya, Anda dapat menggunakan strategi mengutamakan jaringan dengan waktu tunggu untuk memprioritaskan konten yang diperbarui, tetapi hanya jika respons muncul dalam nilai minimum yang Anda tetapkan. Anda juga dapat menggabungkan respons yang di-cache dengan respons jaringan dan membuat respons yang kompleks dari pekerja layanan.
Memperbarui aset
Memastikan aset yang di-cache PWA Anda tetap terbaru bisa menjadi tantangan. Meskipun strategi basi saat divalidasi ulang adalah salah satu cara untuk melakukannya, bukan satu-satunya cara. Di Update chapter, Anda akan mempelajari berbagai teknik untuk terus memperbarui konten dan aset aplikasi.