Codelab ini menunjukkan cara menerapkan pengalaman penelusuran yang tangguh dengan Workbox. Aplikasi demo yang digunakan berisi kotak penelusuran yang memanggil endpoint server, dan mengalihkan pengguna ke halaman HTML dasar.
Ukur
Sebelum menambahkan pengoptimalan, sebaiknya analisis status aplikasi saat ini terlebih dahulu.
- Klik Remix to Edit untuk menjadikan project dapat diedit.
- Untuk melihat pratinjau situs, tekan Lihat Aplikasi. Kemudian tekan Layar Penuh .
Di tab baru yang baru saja dibuka, periksa perilaku situs saat offline:
- Tekan `Control+Shift+J` (atau `Command+Option+J` di Mac) untuk membuka DevTools.
- Klik tab Jaringan.
- Buka Chrome DevTools dan pilih panel Jaringan.
- Di menu drop-down Throttling, pilih Offline.
- Di aplikasi demo, masukkan kueri penelusuran, lalu klik tombol Telusuri.
Halaman error browser standar akan ditampilkan:
Memberikan respons penggantian
Pekerja layanan berisi kode untuk menambahkan halaman offline ke daftar pra-cache, sehingga halaman tersebut selalu dapat di-cache pada peristiwa install
pekerja layanan.
Biasanya, Anda harus menginstruksikan Workbox untuk menambahkan file ini ke daftar pra-cache pada waktu build, dengan mengintegrasikan library dengan alat build pilihan Anda (misalnya webpack atau gulp).
Untuk mempermudah, kami telah melakukannya untuk Anda. Kode berikut di public/sw.js
melakukan hal tersebut:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Selanjutnya, tambahkan kode untuk menggunakan halaman offline sebagai respons penggantian:
- Untuk melihat sumber, tekan Lihat Sumber.
- Tambahkan kode berikut ke bagian bawah
public/sw.js
:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
Kode tersebut melakukan hal berikut:
- Menentukan strategi Khusus Jaringan default yang akan berlaku untuk semua permintaan.
- Mendeklarasikan pengendali error global, dengan memanggil
workbox.routing.setCatchHandler()
untuk mengelola permintaan yang gagal. Jika permintaan ditujukan untuk dokumen, halaman HTML offline penggantian akan ditampilkan.
Untuk menguji fungsi ini:
- Kembali ke tab lain yang menjalankan aplikasi Anda.
- Setel menu drop-down Throttling kembali ke Online.
- Tekan tombol Kembali di Chrome untuk kembali ke halaman penelusuran.
- Pastikan kotak centang Nonaktifkan cache di DevTools dinonaktifkan.
- Tekan lama tombol Muat ulang Chrome, lalu pilih Kosongkan cache dan muat ulang secara paksa untuk memastikan bahwa service worker Anda telah diupdate.
- Setel menu drop-down Throttling kembali ke Offline lagi.
- Masukkan kueri penelusuran, lalu klik tombol Telusuri lagi.
Halaman HTML penggantian ditampilkan:
Meminta izin notifikasi
Agar lebih praktis, halaman offline di views/index_offline.html
sudah berisi kode untuk meminta izin notifikasi dalam blok skrip di bagian bawah:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Kode tersebut melakukan hal berikut:
- Saat pengguna mengklik subscribe to notifications, fungsi
requestNotificationPermission()
akan dipanggil, yang memanggilNotification.requestPermission()
, untuk menampilkan dialog izin browser default. Promise diselesaikan dengan izin yang dipilih oleh pengguna, yang dapat berupagranted
,denied
, ataudefault
. - Meneruskan izin yang di-resolve ke
showOfflineText()
untuk menampilkan teks yang sesuai kepada pengguna.
Mempertahankan kueri offline dan mencoba lagi saat kembali online
Selanjutnya, terapkan Sinkronisasi Latar Belakang Workbox untuk mempertahankan kueri offline, sehingga kueri tersebut dapat dicoba lagi saat browser mendeteksi bahwa konektivitas telah kembali.
- Buka
public/sw.js
untuk mengedit. - Tambahkan kode berikut di akhir file:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
Kode tersebut melakukan hal berikut:
workbox.backgroundSync.Plugin
berisi logika untuk menambahkan permintaan yang gagal ke antrean sehingga dapat dicoba lagi nanti. Permintaan ini akan dipertahankan di IndexedDB.maxRetentionTime
menunjukkan durasi permintaan dapat dicoba ulang. Dalam hal ini, kita telah memilih 60 menit (setelah itu akan dihapus).onSync
adalah bagian terpenting dari kode ini. Callback ini akan dipanggil saat koneksi kembali sehingga permintaan yang diantrekan diambil, lalu diambil dari jaringan.- Respons jaringan ditambahkan ke cache
offline-search-responses
, dengan menambahkan parameter kueri¬ification=true
, sehingga entri cache ini dapat diambil saat pengguna mengklik notifikasi.
Untuk mengintegrasikan sinkronisasi latar belakang dengan layanan Anda, tentukan strategi NetworkOnly untuk permintaan ke URL penelusuran (/search_action
) dan teruskan bgSyncPlugin
yang ditentukan sebelumnya. Tambahkan kode berikut ke bagian bawah public/sw.js
:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
Tindakan ini akan memberi tahu Workbox untuk selalu membuka jaringan, dan, jika permintaan gagal, gunakan logika sinkronisasi latar belakang.
Selanjutnya, tambahkan kode berikut ke bagian bawah public/sw.js
untuk menentukan strategi penyimpanan dalam cache untuk permintaan yang berasal dari notifikasi. Gunakan strategi CacheFirst, sehingga dapat ditayangkan dari cache.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
Terakhir, tambahkan kode untuk menampilkan notifikasi:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
Menguji fitur
- Kembali ke tab lain yang menjalankan aplikasi Anda.
- Setel menu drop-down Throttling kembali ke Online.
- Tekan tombol Kembali di Chrome untuk kembali ke halaman penelusuran.
- Tekan lama tombol Muat ulang Chrome, lalu pilih Kosongkan cache dan muat ulang secara paksa untuk memastikan bahwa service worker Anda telah diupdate.
- Setel menu drop-down Throttling kembali ke Offline lagi.
- Masukkan kueri penelusuran, lalu klik tombol Telusuri lagi.
- Klik berlangganan notifikasi.
- Saat Chrome menanyakan apakah Anda ingin memberikan izin kepada aplikasi untuk mengirim notifikasi, klik Izinkan.
- Masukkan kueri penelusuran lain, lalu klik tombol Telusuri lagi.
- Setel menu drop-down Throttling kembali ke Online lagi.
Setelah koneksi kembali, notifikasi akan ditampilkan:
Kesimpulan
Workbox menyediakan banyak fitur bawaan untuk membuat PWA Anda lebih tangguh dan menarik. Dalam codelab ini, Anda telah mempelajari cara menerapkan Background Sync API melalui abstraksi Workbox, untuk memastikan kueri pengguna offline tidak hilang, dan dapat dicoba lagi setelah koneksi kembali. Demo ini adalah aplikasi penelusuran sederhana, tetapi Anda dapat menggunakan implementasi serupa untuk skenario dan kasus penggunaan yang lebih kompleks, termasuk aplikasi chat, memposting pesan di jejaring sosial, dll.