Tutorial — Defer Operasi Ketika Koneksi Internet Tidak Stabil Dengan Background-Sync

Muhammad Rizki Rijal
hammercode
Published in
7 min readOct 18, 2017

Suatu ketika, Saya sedang dalam perjalanan dari suatu kota ke kota yang lain. Di perjalanan tersebut, Saya berada dalam jangkauan internet yang baik. Namun tidak jarang juga tiba-tiba berada dalam jangkauan internet yang lemah bahkan tidak terjangkau sama sekali, dalam waktu yang lama.

2 tahun belakangan, mungkin teman-teman sering dengar istilah PWA (progressive web app). Apa sih PWA itu? Saya sarankan untuk membaca artikel berikut:

Kasarannya, PWA memungkinkan Kita menggunakan aplikasi web layaknya native mobile app. Dengan PWA, Kita juga dapat mengakses konten dengan cepat walau dalam keadaan koneksi internet yang buruk bahkan offline sekalipun. Hal ini dimungkinkan oleh API baru dari browser modern, Service Worker. Jika ingin mengetahui gambaran umum tentang service worker, berikut artikel yang Saya buat beberapa waktu lalu:

Service Worker merupakan fitur eksperimental. Dikarenakan spesifikasinya belum stabil, API-nya sangat mungkin akan mengalami perubahan.

Skenario Masalah

Anggap saja, Kita memiliki aplikasi web daftar resep makanan yang seperti ini https://background-sync-example-ogeojjtztu.now.sh. Aplikasi ini sudah support akses offline terhadap halaman yang telah dibuka sebelumnya. Bagaimana cara kerjanya, ketika halaman dibuka dalam keadaan koneksi internet tersedia maka response seperti file html, css, js dan lainnya dari halaman tersebut akan di-cache menggunakan Cache API oleh service worker. Sehingga memungkinkan akses offline terhadap halaman tersebut di masa mendatang.

Seperti yang telah disampaikan di awal, pasti beberapa dari Kita juga mangalami hal yang sama. Untuk mensimulasi kejadian tersebut, ayo Kita coba untuk mengakses halaman utama aplikasi tersebut dalam keadaan koneksi internet tersedia dengan baik.

Kemudian koneksi internet Kita putus. Ketika mencoba untuk mengakses halaman detail resep makanan (yang belum pernah dikunjungi sebelumnya), maka kita akan menjumpai tampilan seperti ini.

Tentu ini akan berdampak pada user experience yang buruk. Untuk mengatasi hal ini, pendekatan yang terbaik yang bisa Saya pikirkan adalah Kita buat aplikasi tersebut menampilkan pesan bahwa konten yang diinginkan sedang tidak bisa diakses, akan tetapi aplikasi tersebut bisa memberikannya ketika koneksi internet kembali tersedia.

Dengan kondisi yang seperti ini Kita bisa menunda/defer operasi ini di background dengan Background Sync.

Ilustrasi Alur. Segitiga merah menandakan offline, segitiga hijau online

Starting Point

Mengikuti tutorial ini, asumsi Saya adalah teman-teman sudah familiar dengan Node JS, Webpack, ES 2015+ dan biasa menggunakan git, terminal dan developer tools. Juga Kita akan menggunakan browser Google Chrome :P

Pertama, mari Kita clone starter project dari github.

git clone https://github.com/eezhal92/bg-sync-demo.git

Jika telah selesai, install dependensi project.

npm install

atau

yarn install

Setelah dependensi berhasil ter-install, lalu jalankan projectnya.

npm run dev

Kemudian buka alamat http://localhost:8080 di browser. Maka akan tampil halaman seperti ini.

Sebelum kita lanjut, Kita perlu melakukan sedikit pengaturan. Buka chrome developer tools kemudian ke tab Application. Lalu pilih Service Workers di tab sebelah kiri. Centang pilihan Update on reload. Hal ini Kita lakukan agar setiap perubahan yang dilakukan, baik pada file service worker maupun file source lainnya akan langsung berjalan ketika reload.

Pengaturan Chrome Developer Tools

Overview

Background Sync

Background Sync merupakan bagian dari spek service worker untuk menyediakan event service worker yang bisa dieksekusi di background.

Contoh penggunaan dalam konteks service worker:

Event ini akan dieksekusi ketika browser mengetahui user mempunyai koneksi internet. Dalam contoh di atas, bila Promise yang dikembalikan oleh function sendEveryThingInTheOutbox di-reject, maka function tersebut akan kembali dipanggil pada masa mendatang. Bila Promise tersebut di-resolve, maka function tidak akan dipanggil, karena proses sync telah berhasil.

Tentang Aplikasi

Aplikasi ini hanya memiliki 2 halaman dibuat dengan Vanilla JS tanpa UI library atau framework. Halaman index.html untuk menampilkan daftar resep dan halaman detail.html untuk menampilkan detail resep. Masing-masing halaman index.html dan detail.html memiliki file JavaScript index.js dan detail.js secara respektif. Untuk implementasi background sync kita hanya akan fokus pada halaman detail.html

Kode yang harus ditulis dan dihapus untuk setiap tahap disediakan dalam bentuk link commit diff.

Menampilkan Tawaran Background Sync

Okay, tahap pertama Kita ingin menampilkan pesan ketika user mencoba mengakses halaman detail resep dalam keadaan offline.

Sampai di sini, Kita hanya baru menampilkan pesan. Selanjutnya Kita ingin button pada pesan tersebut, memiliki event handler. Ketika user meng-klik button maka proses background sync akan dijalankan. Lalu aplikasi akan menampilkan pesan kedua tentang notifikasi akan muncul ketika konten telah tersedia.

Setelah itu, Kita beri tahu service worker bahwa Kita ingin melakukan register sync.

Untuk mengetahui apakah proses ini berhasil atau tidak, Kita membuat sebuah mock function handleSyncExample pada file sw.js. Function ini akan dieksekusi ketika koneksi internet kembali normal.

Nantinya function handleSyncExample akan kita ganti dengan function baru dengan implementasi yang benar.

Event sync pada service worker akan terpicu ketika internet kembali normal [Need to be updated]

Seperti yang terlihat di gambar di atas, aplikasi berhasil melakukan handling background sync.

Kalau teman-teman perhatikan, ketika mengakses halaman detail resep dari halaman utama, di address bar akan ada hash seperti ini #recipe_id=1. Ini Kita gunakan untuk menyimpan informasi unique identifier dari resep yang akan kita ambil dari server. Untuk menyimpan identifier ini Kita akan menggunakan package localforage. Mari kita install package tersebut, jalankan:

$ npm install localforage

atau

$ yarn add localforage

Setelah ter-install, kita buat function queue pada file sync.js. Fungsi ini untuk menyimpan identifier-identifier resep yang akan kita load di background.

Sampai di poin ini, function offerBgSync pada file detail.js menjadi seperti ini:

Saya akan menjelaskan alur dari function ini.

  1. Ketika request data untuk detail suatu resep gagal karena koneksi internet, makan function ini akan dipanggil.
  2. Kita tampilkan pesan apakah user ingin me-load konten di background. Kemudian, button pada pesan tersebut kita beri event handler.
  3. Bila user setuju dan meng-klik button tersebut, Kita akan meminta persetujuan lagi dari user untuk notifikasi.
  4. Bila user setuju lagi, identifier resep akan dimasukkan ke dalam list di storage.
  5. Kita lakukan register terhadap event background sync dengan memberi tag load-recipe. Tag ini berguna jika kalian ingin membedakan antara handler untuk event background yang satu dan yang lainnya. Misal tag post-comment untuk handling ketika user mengirim komentar tentang resep ketika offline.
  6. Terakhir pesan akan muncul untuk memberitahu user bahwa notifikasi akan muncul ketika konten telah tersedia.

Sekarang coba putus koneksi internet, dan akses salah satu halaman resep.

Bila kita setuju untuk me-load resep tersebut di background, maka informasi identifier dari resep tersebut akan tersimpan di IndexedDB. Proses ini telah di-abstraksi oleh localforage untuk Kita.

Selanjutnya, Kita akan buat function handleLoadRecipeSync untuk menggantikan mock function handleSyncExample yang sebelumnya Kita buat.

Jika butuh meng-unregister service worker dan menghapus cache secara manual, Teman-teman bisa buka dev tools, kemudian ke tab Application. Terdapat tab Service Workers dan tab Cache Storage. Di kedua tab tersebut un-register service worker dan hapus cache.

Coba kembali lagi. Maka akan muncul notifikasi. ketika klik, muncul artikel yang sebelumnya di load di background.

Lalu kita coba sekali lagi, namun ketika notifikasi datang koneksi internet akan Kita putus. Setelah itu coba klik notifikasi tersebut.

Hmmm, hasil yang seperti ini bukan yang Kita harapkan. Hal ini terjadi karena Kita tidak melakukan caching terhadap response yang diterima saat handling sync. Maka langkah selanjutnya adalah lakukan caching setelah response diterima.

Jika kita coba lagi dalam keadaan offline, maka bisa konten bisa diakses.

Yeah! 🎉🎉🎉

Penutup

Yang telah Kita buat hanya demo sederhana tentang kemampuan background sync. Tentunya kita bisa menggunakan fitur ini untuk mengakomodasi kebutuhan yang lebih kompleks.

Bila terdapat kesalahan atau pertanyaan, silakan beri komentar. Jika tutorial ini bermanfaat bisa dibagikan ke yang lain 😄. Thanks, Sampai jumpa di artikel atau tutorial selanjutnya!

--

--