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 untuk Mengedit 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 Network
  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 akan ditampilkan:

Screenshot UX offline default di browser.

Memberikan respons penggantian

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

Biasanya Anda perlu menginstruksikan Workbox untuk 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 melakukannya:

const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);

Berikutnya, 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 Khusus Jaringan default yang akan diterapkan ke 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:

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

Halaman HTML penggantian ditampilkan:

Screenshot UX offline kustom pada 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() akan dipanggil, yang memanggil Notification.requestPermission(), untuk menampilkan permintaan izin browser default. Promise di-resolve dengan izin yang diambil oleh pengguna, yang bisa 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 Workbox Background Sync untuk mempertahankan kueri offline agar 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 agar dapat dicoba lagi nanti. Permintaan ini akan disimpan di IndexedDB.
  • maxRetentionTime menunjukkan jumlah 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 akan diambil, lalu diambil dari jaringan.
  • Respons jaringan ditambahkan ke cache offline-search-responses, dengan menambahkan parameter kueri &notification=true, sehingga entri cache ini dapat diambil ketika 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],
  }),
);

Ini akan memberi tahu Workbox untuk selalu menuju jaringan, dan jika permintaan gagal, gunakan logika sinkronisasi latar belakang.

Selanjutnya, tambahkan kode berikut ke bagian bawah public/sw.js untuk menentukan strategi caching untuk permintaan yang berasal dari notifikasi. Gunakan strategi CacheFirst agar dapat disalurkan 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 kembali menu drop-down Throttling ke Online.
  3. Tekan tombol Kembali pada Chrome untuk kembali ke halaman penelusuran.
  4. Tekan lama tombol Reload Chrome, lalu pilih Empty cache and hard reload untuk memastikan pekerja layanan Anda telah diupdate.
  5. Setel daftar drop-down Throttling kembali ke Offline.
  6. Masukkan kueri penelusuran, lalu klik tombol Telusuri lagi.
  7. Klik berlangganan notifikasi.
  8. Jika Chrome menanyakan apakah Anda ingin memberikan izin kepada aplikasi untuk mengirim notifikasi, klik Izinkan.
  9. Masukkan kueri penelusuran lain, lalu klik tombol Telusuri lagi.
  10. Setel menu drop-down Throttling kembali ke Online lagi.

Setelah koneksi kembali terhubung, 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 bahwa 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 jaringan sosial, dll.