Membangun pengalaman penelusuran yang andal dengan Workbox

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 agar project dapat diedit.
  • Untuk melihat pratinjau situs, tekan Lihat Aplikasi. Lalu tekan Layar penuh layar penuh.

Di tab baru yang baru saja terbuka, periksa perilaku situs saat offline:

  1. Tekan `Control+Shift+J` (atau `Command+Option+J` di Mac) untuk membuka DevTools.
  2. Klik tab Jaringan.
  3. Buka Chrome DevTools dan pilih panel Jaringan.
  4. Di menu drop-down Throttling, pilih Offline.
  5. Di aplikasi demo, masukkan kueri penelusuran, lalu klik tombol Telusuri.

Halaman error browser standar ditampilkan:

Screenshot UX offline default di browser.

Memberikan respons penggantian

Pekerja layanan berisi kode untuk menambahkan halaman offline ke daftar pra-cache, sehingga dapat selalu di-cache pada peristiwa install pekerja layanan.

Biasanya, Anda perlu menginstruksikan Workbox agar menambahkan file ini ke daftar precache 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:

  1. Untuk melihat sumber, tekan Lihat Sumber.
  2. 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 Hanya Jaringan default yang akan diterapkan ke semua permintaan.
  • Mendeklarasikan pengendali error global, dengan memanggil workbox.routing.setCatchHandler() untuk mengelola permintaan yang gagal. Saat permintaan ditujukan untuk dokumen, halaman HTML offline pengganti akan ditampilkan.

Untuk menguji fungsi ini:

  1. Kembali ke tab lain yang menjalankan aplikasi Anda.
  2. Setel drop-down Throttling kembali ke Online.
  3. Tekan tombol Kembali di Chrome untuk kembali ke halaman penelusuran.
  4. Pastikan kotak centang Disable cache di DevTools dinonaktifkan.
  5. Tekan lama tombol Reload Chrome, lalu pilih Kosongkan cache dan muat ulang paksa untuk memastikan pekerja layanan Anda diupdate.
  6. Setel drop-down Throttling kembali ke Offline lagi.
  7. Masukkan kueri penelusuran, dan klik tombol Telusuri lagi.

Halaman HTML penggantian ditampilkan:

Screenshot UX offline kustom di browser.

Meminta izin notifikasi

Untuk mempermudah, 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 berlangganan notifikasi, fungsi requestNotificationPermission() dipanggil, yang memanggil Notification.requestPermission(), untuk menampilkan dialog izin browser default. Promise di-resolve dengan izin yang diambil oleh pengguna, yang dapat berupa granted, denied, atau default.
  • Meneruskan izin yang telah di-resolve ke showOfflineText() untuk menampilkan teks yang sesuai kepada pengguna.

Pertahankan kueri offline dan coba 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.

  1. Buka public/sw.js untuk mengedit.
  2. 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}&notification=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 lamanya waktu permintaan dapat dicoba lagi. 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, menambahkan parameter kueri &notification=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 telah 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 masuk ke jaringan, dan, jika permintaan gagal, gunakan logika sinkronisasi latar belakang.

Selanjutnya, tambahkan kode berikut ke bagian bawah public/sw.js guna 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

  1. Kembali ke tab lain yang menjalankan aplikasi Anda.
  2. Setel drop-down Throttling kembali ke Online.
  3. Tekan tombol Kembali di Chrome untuk kembali ke halaman penelusuran.
  4. Tekan lama tombol Reload Chrome, lalu pilih Kosongkan cache dan muat ulang paksa untuk memastikan pekerja layanan Anda diupdate.
  5. Setel drop-down Throttling kembali ke Offline lagi.
  6. Masukkan kueri penelusuran, dan klik tombol Telusuri lagi.
  7. Klik berlangganan notifikasi.
  8. Saat Chrome menanyakan apakah Anda ingin memberikan izin kepada aplikasi untuk mengirim notifikasi, klik Izinkan.
  9. Masukkan kueri penelusuran lain dan klik tombol Telusuri lagi.
  10. Setel drop-down Throttling kembali ke Online lagi.

Setelah koneksi kembali tersedia, notifikasi akan ditampilkan:

Screenshot alur offline lengkap.

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 penerapan serupa untuk skenario dan kasus penggunaan yang lebih kompleks, termasuk aplikasi chat, memposting pesan di jejaring sosial, dll.