Sinkronisasi Data pada Offline First Web App

Ahmad 'Ans' Syuhada
Pujangga Teknologi
Published in
9 min readMar 6, 2019

Tulisan ini melengkapi materi presentasi “Challenges on Offline First Web App” untuk meetup BandungJS Februari 2019

Sekapur sirih

Diambil dari http://offlinefirst.org/

Perkembangan teknologi web dan infrastruktur koneksi mobile internet semakin maju dan selayaknya pembangunan infrastruktur, kota dan pusat pertumbuhan manusia menikmati kemajuan teknologi tersebut. Namun ditengah-tengah kemajuan tersebut ada bias dalam pengembangan teknologi web. Meskipun di kota dan kebanyakan dari kita menikmatinya, tidak setiap saat tersedia koneksi mobile internet yang memadai. Bisa cek situs ini deh. Apalagi di daerah jauh dari “pusat peradaban” itu, seperti di desa, bahkan daerah transisi kota pun belum tentu, disebut “desa bukan dan kota belum”. Padahal daerah tersebut biasa menjadi kawasan hunian masyarakat kota/urban. Apakah koneksi internet pasti ada?

Gambar legendaris sebagai indikator batas garis kemiskinan koneksi internet

Google sendiri mulai kampanye “Next Billion Users” dalam pengembangan teknologinya. Teknologi semacam PWA dengan Service Worker datang untuk memberi kemudahan dalam pengembangan mengatasi koneksi internet yang tidak selalu tersedia. Dengan teknologi ini kita dapat menyediakan aset, data dari lokal dahulu sehingga dapat tampil lebih cepat. Namun apakah itu cukup? Bagaimana bila kita harus membuat aplikasi yang dapat tersinkronisasi datanya saat internet kembali tersedia?

Pada artikel kali ini kita coba mengenali dahulu Offline First untuk melihat tantangan-tantangan dalam membuat aplikasi web bagi koneksi internet terbatas. Lalu kita akan kenali teknologi untuk membuat aplikasi web yang memudahkan saat sinkronisasi data ketika koneksi internet didapatkan.

Apa itu Offline First?

Offline First ini sebuah cara berpikir dan juga nama gerakan serupa yang isinya membahas teknologi serta pengembangan produk dengan cara berpikir tersebut. Offline First tidak sama dengan PWA (Offline First !== PWA). Dalam pengembangan web traditional seperti ini.

Diambil dari https://hackernoon.com/turtledb-a-javascript-framework-for-building-offline-first-collaborative-web-apps-7183cd787163

Setiap request browser akan mengunduh aset HTML, CSS, JS lalu melakukan render, lalu kode JS mungkin akan me-request data dan melakukan render kembali. Bagaimana dengan pola pikir Offline First?

Diambil dari https://hackernoon.com/turtledb-a-javascript-framework-for-building-offline-first-collaborative-web-apps-7183cd787163

Aset yang ada sudah diunduh dan dipertahankan/di-cache di browser dahulu, sehingga render dilakukan dari hasil cache, bahkan data pun disediakan dari cache untuk render. Lebih jauh, data yang diubah dengan interaksi pun disimpan ke lokal dahulu baru dikirim ke cloud. Teknik ini bisa dengan menggunakan browser cache maupun service worker.

Jadi ada 3 kata kunci untuk hal ini bila boleh saya simpulkan:

  1. Offline Assets
  2. Offline Data
  3. Pola Pikir Offline First

Kenapa harus Offline First?

Seperti sudah disampaikan di awal artikel, tidak setiap saat kita memiliki akses internet memadai. Hal ini membuat pendekatan teknologi yang kita buat akan berbeda. Secara arsitektural akan lebih sulit bila kita berangkat dari pendekatan aplikasi yang selalu online. Namun apabila dari awal kita sudah merancang untuk siap dengan kondisi offline, akan lebih mudah untuk pengembangan selanjutnya bila harus menyediakan kapabilitas online. Secara diagram arsitektur singkatnya seperti ini pendekatannya.

Diambil dari https://tech.trello.com/sync-architecture/

Secara pribadi saya mendukung dengan pendekatan ini karena pengalaman di kendala pekerjaan. Saat itu kami membuat aplikasi ponsel untuk mengontrol alat kami dari ponsel, dengan harus mengirim dan menerima data dari internet juga, termasuk sinkronisasi datanya. Pengguna kami bukan penduduk pusat-pusat peradaban kota. Kami mengalami kesulitan dan kesalahan perancangan di awal, baru sadar dan tercerahkan setelah membaca artikel Trello ini dan itu. Lalu kami merombak implementasinya dan ternyata tidak semudah itu Ferguso.

Diambil dari https://www.kaskus.co.id/thread/5be658d614088d845d8b4572/mengenal-viralnya-meme-quottidak-semudah-itu-fergusoquot/

Meski cukup berhasil mengimplementasikannya pada kasus khusus kami, tapi itu dengan berbagai pembelajaran berharga s̶e̶r̶t̶a̶ ̶d̶a̶r̶a̶h̶ ̶d̶a̶n̶ ̶a̶i̶r̶ ̶m̶a̶t̶a̶. Selanjutnya kami berpikir lebih awal bila ingin membuat teknologi lainnya (termasuk web) melalui pendekatan ini. Selain karena teknologi ini seru dan menantang untuk diimplementasi :)

Bagaimana Offline First?

Offline Asset

Pertama, terkait offline asset ini saya kira sudah cukup banyak panduan dan artikel yang membahas ini. Seperti contohnya ini. Kebanyakan memang memanfaatkan kapabilitas PWA melalui Service Worker-nya. Jadi tidak perlu saya bahas, kalian bisa telusuri artikel yang sudah ada. Selain itu bagi Anda pelaku pemrograman web yang memakai mazhab React, tentu saja Create React App sudah menyediakan boilerplate yang siap untuk PWA. Jadi masalah hidup sudah berkurang setengahnya. Saya pikir sudah jelas.

Offline Data

Kita akan fokus pada kemampuan offline data ini. Apa sih maksudnya? Data pada aplikasi harus tersedia meskipun tidak ada koneksi internet, perubahan pada data dapat disimpan secara lokal dan bisa tersinkronisasi bila koneksi kembali tersedia. Singkatnya begitu. Teknologi yang biasa digunakan diantaranya Background Sync dan Offline Storage selain Service Worker yang sudah pasti digunakan.

Background Sync digunakan untuk mengatasi pengiriman data hanya saat ada koneksi internet yang memadai, lalu Offline Storage (gunakan IndexedDB) untuk menyimpan dan memanipulasi data secara lokal. Namun pertanyaan di awal kita belum terjawab tentang sinkronisasi datanya. Masih tidak mudah menerapkan hal ini meski dengan berbagai teknologi PWA yang ada.

Terimakasih sudah membaca sampai sejauh ini kawan-kawan yang budiman, mari kita lanjutkan ke bagian yang lebih seru. Siapkan kopi atau minuman kesukaanmu dahulu sebelum lanjut.

Tantangan pengembangan Offline First Sync

Membuat sinkronisasi data pada aplikasi bukan hanya masalah teknis. Kita juga harus memikirkan berbagai hal non-teknis. Diantaranya yang pernah saya dan tim (kami) temui dalam pekerjaan, semoga bisa menjadi patokan bagi teman-teman pembaca.

Pilih jenis storage dan strategi menyimpannya

Menyimpan data di browser ini harus cukup cerdik. Pertama, jenis storage yang digunakan karena keterbatasan ukuran penyimpanan di browser, termasuk cara querying-nya. Kami menyarankan menggunakan IndexedDB. Selain ukurannya lebih besar (meski tetap terbatas), sudah banyak browser kompatibel dengan IndexedDB. Setelah itu perlu juga kita pikirkan bagaimana mempertahankan datanya (cache). Karena tidak bisa kita menyimpan semua data secara lokal. Pastikan strategi ini dahulu tergantung karakter aplikasi yang akan Anda buat. Misal untuk aplikasi penyedia konten tertulis tidak perlu menyimpan gambar, cukup alamat URL-nya saja. Hanya saat ada koneksi internet maka aplikasi akan menampilkan gambar dari internet, selain yang sudah di-cache sebelumnya.

Pilih strategi kapan harus sync dan UX-nya

Apabila Anda membuat aplikasi yang memungkinkan menampilkan perubahan data yang dapat digunakan offline. Pastikan memikirkan kapan harus mengambil atau mengirimkan data. Hal ini bisa dipilih apakah harus real time, terjadwal setiap beberapa periode atau hanya saat pengguna melakukan aksi tertentu (misal menekan tombol). Tujuannya untuk mengurangi beban aplikasi, menghemat baterai dan memberikan pengalaman menyenangkan bagi pengguna. Setelah pengambilan atau pengiriman data, tentunya saat perubahan tersebut perlu disadari oleh pengguna.

Pilih strategi conflict resolution ketika sync dan UX-nya

Apabila Anda memiliki aplikasi yang berjalan offline dan melakukan perubahan data di lokal untuk disinkronisasi dengan lainnya, pada dasarnya Anda melakukan sinkronisasi seperti replikasi basis data terdistribusi. Bedanya lingkungan data terdistribusi ini bukan di cloud, tapi perangkat klien dan basis data utama.

Diambil dari https://searchdatamanagement.techtarget.com/definition/database-replication

Jadi bisa kita anggap Anda perlu memastikan bagaimana mekanisme bila data yang disinkronisasi ada bentrok atau bisa disebut Conflict Resolution. Anda bisa menggunakan pendekatan paling sederhana, hanya menerima data terbaru bila ada data sama yang diubah berbeda waktu. Pendekatan lainnya pun bisa dipilih atau bahkan memberikan klien kebebasan untuk memilih data mana yang akan digunakan. Serta pastikan aplikasi cloud atau basis data utama Anda di cloud mendukung mekanisme ini.

Pilih strategi implementasi komponennya

Pada saat kami melakukan implementasi ini, kami menggunakan pustaka React untuk Javascript.

Arsitektur komponen saat implementasi aplikasi

Pada akhirnya kami memutuskan tidak memakai Redux untuk implementasi. Karena pilihan teknologi kami untuk melakukan sinkronisasi data lebih mudah diatasi bila kami tidak menambah komponen global state. Kembali lagi pada arsitektur awal yang kami baca dari Trello. Perantara tampilan dengan data dari cloud ada di basis data lokal.

Kesimpulan hal ini kami melihat kemudahannya bila akan mengubah aplikasi ini menjadi online first untuk beberapa bagian. Kami cukup mengubah aksi yang harusnya ke lokal, menjadi ke cloud saja. Dengan bisa memberikan abstraksi yang sama.

Pustaka dan “Pusaka” untuk Offline First Sync

Bagaimana, minumannya masih ada? Kita lanjut dahulu ya. Memang terlihat pusing, banyak hal yang kita pikirkan. Betul itu. Makanya kita tak perlu susah-susah memikirkan hal itu lagi seperti dahulu kami alami. Kami sudah merangkum beberapa kumpulan teknologi yang langsung mendukung sinkronisasi data aplikasi offline first agar lebih cepat v̶e̶r̶s̶i̶ ̶o̶n̶ ̶t̶h̶e̶ ̶s̶p̶*̶t̶.

Pustaka-pustaka Offline First Sync

Firebase atau Firestore

Pilihan pertama ini sudah sangat jelas dan cukup lengkap dari penyedia cloud dan pustaka untuk klien lokal. Basis data No SQL yang dapat langsung dipakai out of the box. Baiknya Anda menggunakan Firestore, karena lebih terkini pengembangannya. Pustakanya sendiri mendukung offline data dari awal. Kami pun saat awal-awal membuat aplikasi, memanfaatkan ini dahulu sambil belajar membuatnya. Tapi ada beberapa keterbatasan dengan solusi ini.

Pertama, pay as you scale, dengan banyak cerita ajaib dan kita juga alami, seperti ini. Kemampuan querying yang terbatas dan juga fitur sync dan multitab yang masih eksperimental.

Diambil dari https://firebase.googleblog.com/2018/09/multi-tab-offline-support-in-cloud.html

CouchDB + PouchDB

CouchDB merupakan basis data No SQL yang memiliki kemampuan sinkronisasi multi master dengan transaksi data melalui HTTP/JSON API. Sedangkan PouchDB adalah implementasi basis data di Javascript yang mirip dengan CouchDB. Terutama karena memakai protokol replikasi yang sama dengan CouchDB. Hal ini membuat data di lokal/klien dapat langsung tereplikasi satu arah, dua arah dengan data di klien lain atau cloud, terlebih melalui transaksi HTTP. Bila ingin mengetahui detail transaksi HTTP-nya bisa cek artikel ini.

Penggunaan di PouchDB sendiri untuk replikasi sangat mudah hanya

const localDB = new PouchDB('mylocaldb')
const remoteDB = new PouchDB('http://couchdb-url:5984/myremotedb')
// kode untuk replikasi
localDB.replicate.to(remoteDB);
localDB.replicate.from(remoteDB);
// bisa juga dengan code
localDB.sync(remoteDB);
// tapi saya tidak prefer ini

Replikasi data dari dan ke lokal/remote dapat dilakukan dengan mudah. Apabila butuh realtime, bahkan bisa melakukan hal ini langsung:

const handlerRemoteChange = localDB.replicate.from(remoteDB, {
live: true,
retry: true,
}).on('change', change => {
// yo, something changed!
}).on('error', err => {
// yo, something error!
})
// untuk berhenti watch realtime
handlerRemoteChange.cancel();

TortoiseDB + TurtleDB

Kami belum pernah mencoba hal ini. Jadi bila ada pembaca yang tertarik mencoba bisa cek artikel ini.

Kami sendiri memilih pustaka CouchDB+PouchDB untuk implementasi dan membuat sendiri pustaka khusus (pusaka) pada PouchDB dengan React untuk memudahkan hidup kami.

“Pusaka” untuk Offline First Sync + React

Pusaka ini dalam artian pustaka terkustomisasi yang memudahkan penggunaannya. Kami menggunakan React dengan membuat pustaka ini sebagai abstraksi terhadap basis data lokal. Kami namakan “PouchyStore”.

Arsitektur komponen “pusaka” kami yang memanfaatkan pustaka CouchDB + PouchDB dalam React

Saat ini masih eksperimental, mungkin masih banyak bug dan fitur yang belum tersedia. Utamanya pustaka ini memudahkan untuk simpan, baca, perbaharui data lokal dan remote tersinkronisasi. Anda dapat mencoba menggunakannya dari NPM ini.

Anda bisa lihat implementasinya dan fokus pada bagian initialize. Kami pun sedikit menambahkan interface pada PouchDB dengan metode-metode khusus kebutuhan kami.

Bisa dilihat kami membuat fungsi untuk abstraksi terkait upload, watchRemote, watchLocal, [add|edit|delete]Item, countUnuploaded. Semua ini agar memudahkan penggunaannya menjadi ringkas tinggal

Contoh Aksi Implementasi Offline First Sync

Kita membuat aplikasi sederhana ToDo seperti umumnya tutorial-tutorial lain. Pertama kita tambahkan dua item dari web dan mobile saat online.

Lalu aplikasi mobile kita mengalami kehilangan koneksi dan menambahkan item baru serta menghapus item sebelumnya

Setelah itu kita aktifkan kembali koneksi internet mobile. Aplikasi web dan mobile datanya sudah tersinkronisasi kembali tanpa kendala

Berikutnya

Pelajaran utamanya apabila sudah ada protokol yang tersedia tidak perlu membuat ulang lagi dari awal. Apabila pustaka ini sudah siap untuk dirilis, kami akan beritahu lebih lanjut :)

P.S. Jika teman-teman menyukai artikel semacam ini, silakan subscribe ke newsletter kita dan dapatkan notifikasi artikel terbaru langsung di inbox kamu!

--

--

Ahmad 'Ans' Syuhada
Pujangga Teknologi

Seorang sederhana dengan pemikiran tidak sederhana. Kalau sederhana semua, rumah makan padang namanya.