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 dengan origin yang sama maupun permintaan lintas origin. Selain permintaan navigasi dan aset, pengambilan dari pekerja layanan yang diinstal memungkinkan kunjungan halaman setelah pemuatan pertama situs dirender tanpa panggilan jaringan.
Pengendali fetch
menerima semua permintaan dari aplikasi, termasuk URL dan header HTTP, serta memungkinkan developer aplikasi memutuskan cara memprosesnya.
Pekerja layanan 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, dan bagaimana permintaan tersebut ditampilkan ke PWA, bahkan saat pengguna sedang offline.
Untuk merespons permintaan yang 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 harus menampilkan objek Response. Namun, Anda tidak dapat memanggil respondWith()
setelah pengendali peristiwa pengambilan selesai, seperti dalam panggilan asinkron. Jika perlu menunggu respons lengkap, Anda dapat meneruskan Promise ke respondWith()
yang diselesaikan dengan Response.
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, dengan menetapkan isi dan opsi 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
Setelah Anda mengetahui cara menayangkan respons HTTP dari pekerja layanan, saatnya menggunakan antarmuka Penyimpanan Cache untuk menyimpan aset di perangkat.
Anda dapat menggunakan API penyimpanan cache untuk memeriksa apakah permintaan yang diterima dari PWA tersedia di cache, dan jika ya, respons respondWith()
dengan permintaan tersebut.
Untuk melakukannya, Anda harus menelusuri dalam cache terlebih dahulu. Fungsi match()
, yang tersedia di antarmuka caches
tingkat teratas, menelusuri semua penyimpanan di origin Anda, atau di satu objek cache terbuka.
Fungsi match()
menerima permintaan HTTP atau URL sebagai argumen dan menampilkan promise yang di-resolve dengan Respons 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 Anda sendiri untuk mengirimkan aset untuk PWA Anda.
Anda tidak dibatasi pada satu strategi penyimpanan dalam cache. Anda dapat menentukan URL yang berbeda untuk pola URL yang berbeda. Misalnya, Anda dapat memiliki satu strategi untuk aset UI minimum, strategi lain untuk panggilan API, dan strategi ketiga untuk URL gambar dan data.
Untuk melakukannya, baca event.request.url
di ServiceWorkerGlobalScope.onfetch
dan mengurainya 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 kembali ke jaringan jika tidak ditemukan.
- Mengutamakan Jaringan
- Meminta respons dari jaringan terlebih dahulu dan jika tidak ada yang ditampilkan, memeriksa respons di cache.
- Tidak Relevan Saat Melakukan Validasi Ulang
- Menayangkan respons dari cache, sementara di latar belakang meminta versi terbaru dan menyimpannya ke cache untuk saat berikutnya aset diminta.
- Khusus Jaringan
- Selalu membalas dengan respons dari jaringan atau mengalami error. Cache tidak pernah digunakan.
- Khusus Cache
- Selalu membalas dengan respons dari cache atau error. Jaringan tidak akan pernah dikonsultasikan. Aset yang akan ditayangkan menggunakan strategi ini harus ditambahkan ke cache sebelum diminta.
Menyimpan ke cache terlebih dahulu
Dengan strategi ini, pekerja layanan akan mencari permintaan yang cocok di cache dan menampilkan Respons yang sesuai jika di-cache. Jika tidak, respons akan diambil dari jaringan (secara opsional, memperbarui cache untuk panggilan mendatang). Jika tidak ada respons cache atau respons jaringan, permintaan akan mengalami error. Karena penayangan aset tanpa mengakses 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);
}
)
)
});
Jaringan terlebih dahulu
Strategi ini adalah mirror 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 atau respons cache, permintaan akan mengalami 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 berlaku saat memvalidasi ulang
Strategi stale while revalidate langsung menampilkan respons yang di-cache, lalu memeriksa jaringan untuk menemukan update, dan mengganti respons yang di-cache jika ditemukan. Strategi ini selalu membuat permintaan jaringan, karena meskipun resource yang di-cache ditemukan, strategi ini akan mencoba memperbarui resource yang ada di cache dengan resource 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 penayangan cepat strategi cache first 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 khusus jaringan mirip dengan perilaku browser tanpa pekerja layanan atau Cache Storage API. Permintaan hanya akan menampilkan resource jika dapat diambil dari jaringan. Hal ini sering kali berguna untuk resource seperti permintaan API khusus online.
Hanya cache
Strategi khusus 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
dari penyimpanan cache untuk merespons cache saja:
self.addEventListener("fetch", event => {
event.respondWith(caches.match(event.request));
});
Strategi kustom
Meskipun strategi di atas adalah strategi penyimpanan dalam cache yang umum, 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 jaringan terlebih dahulu dengan waktu tunggu untuk memprioritaskan konten yang diperbarui, tetapi hanya jika respons muncul dalam batas yang Anda tetapkan. Anda juga dapat menggabungkan respons yang di-cache dengan respons jaringan dan membuat respons kompleks dari pekerja layanan.
Memperbarui aset
Menjaga aset yang di-cache PWA Anda tetap terbaru bisa menjadi tantangan. Meskipun strategi stale while revalidate adalah salah satu cara untuk melakukannya, strategi ini bukan satu-satunya. Di bab Update, Anda akan mempelajari berbagai teknik untuk terus memperbarui konten dan aset aplikasi.