Praktik Terbaik dalam Menggunakan IndexedDB

Pelajari praktik terbaik untuk menyinkronkan status aplikasi antara library pengelolaan status yang populer di audiens.

Saat pengguna pertama kali memuat situs atau aplikasi, sering kali ada banyak pekerjaan yang harus dilakukan dalam membuat status aplikasi awal yang digunakan untuk merender UI. Misalnya, terkadang aplikasi perlu mengautentikasi sisi klien pengguna, lalu membuat beberapa permintaan API sebelum memiliki semua data yang perlu ditampilkan di halaman.

Menyimpan status aplikasi di IndexedDB dapat menjadi cara yang tepat untuk mempercepat waktu pemuatan untuk kunjungan berulang. Selanjutnya, aplikasi dapat melakukan sinkronisasi dengan layanan API apa pun di latar belakang dan mengupdate UI dengan data baru dengan lambat, menggunakan strategi stale-temporary- revalidate.

Penggunaan lain yang baik untuk IndexedDB adalah untuk menyimpan konten buatan pengguna, baik sebagai penyimpanan sementara sebelum diupload ke server maupun sebagai cache sisi klien dari data jarak jauh - atau, tentu saja, keduanya.

Namun, saat menggunakan IndexedDB, ada banyak hal penting untuk dipertimbangkan yang mungkin tidak segera dipahami oleh developer yang baru mengenal API. Artikel ini menjawab pertanyaan umum dan membahas beberapa hal terpenting yang perlu diingat saat mempertahankan data di IndexedDB.

Menjaga aplikasi Anda dapat diprediksi

Banyak kerumitan di sekitar IndexedDB berasal dari fakta bahwa ada begitu banyak faktor yang tidak dapat Anda kendalikan (developer) Bagian ini mengeksplorasi banyak masalah yang harus Anda ingat saat bekerja dengan IndexedDB.

Tidak semua data dapat disimpan di IndexedDB pada semua platform

Jika menyimpan file buatan pengguna berukuran besar seperti gambar atau video, Anda dapat mencoba menyimpannya sebagai objek File atau Blob. Fitur ini akan berfungsi di beberapa platform, tetapi gagal di platform lainnya. Safari di iOS, khususnya, tidak dapat menyimpan Blob di IndexedDB.

Untungnya, tidak terlalu sulit untuk mengonversi Blob menjadi ArrayBuffer, dan sebaliknya. Menyimpan ArrayBuffer di IndexedDB sangat didukung dengan baik.

Namun, perlu diingat bahwa Blob memiliki jenis MIME, sedangkan ArrayBuffer tidak. Anda harus menyimpan jenis tersebut bersama buffer agar dapat melakukan konversi dengan benar.

Untuk mengonversi ArrayBuffer menjadi Blob, Anda cukup menggunakan konstruktor Blob.

function arrayBufferToBlob(buffer, type) {
  return new Blob([buffer], { type: type });
}

Arah lainnya sedikit lebih terlibat, dan merupakan proses asinkron. Anda dapat menggunakan objek FileReader untuk membaca blob sebagai ArrayBuffer. Saat pembacaan selesai, peristiwa loadend akan dipicu pada pembaca. Anda dapat menggabungkan proses ini dalam Promise seperti berikut:

function blobToArrayBuffer(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener('loadend', () => {
      resolve(reader.result);
    });
    reader.addEventListener('error', reject);
    reader.readAsArrayBuffer(blob);
  });
}

Penulisan ke penyimpanan mungkin gagal

Error saat menulis ke IndexedDB dapat terjadi karena berbagai alasan, dan dalam beberapa kasus alasan ini berada di luar kendali Anda sebagai developer. Misalnya, beberapa browser saat ini tidak mengizinkan penulisan untuk IndexedDB saat dalam mode penjelajahan rahasia. Ada juga kemungkinan bahwa pengguna menggunakan perangkat yang hampir kehabisan ruang disk, dan browser akan membatasi Anda agar tidak menyimpan apa pun.

Oleh karena itu, sangat penting bagi Anda untuk selalu menerapkan penanganan error yang tepat dalam kode postingan Anda. Ini juga berarti, secara umum, sebaiknya pertahankan status aplikasi di dalam memori (selain menyimpannya), sehingga UI tidak rusak saat dijalankan dalam mode penjelajahan rahasia atau saat ruang penyimpanan tidak tersedia (meskipun beberapa fitur aplikasi lain yang memerlukan penyimpanan tidak berfungsi).

Anda dapat menangkap error di operasi TensorFlow dengan menambahkan pengendali peristiwa untuk peristiwa error setiap kali Anda membuat objek IDBDatabase, IDBTransaction, atau IDBRequest.

const request = db.open('example-db', 1);
request.addEventListener('error', (event) => {
  console.log('Request error:', request.error);
};

Data tersimpan mungkin telah diubah atau dihapus oleh pengguna

Tidak seperti database sisi server yang memungkinkan Anda membatasi akses tidak sah, database sisi klien dapat diakses oleh ekstensi browser dan alat developer, serta dapat dihapus oleh pengguna.

Meskipun tidak umum bagi pengguna untuk mengubah data yang disimpan secara lokal, pengguna biasanya menghapus data tersebut. Penting bahwa aplikasi Anda dapat menangani kedua kasus ini tanpa mengalami error.

Data tersimpan mungkin sudah tidak berlaku

Serupa dengan bagian sebelumnya, meskipun pengguna belum memodifikasi data sendiri, ada kemungkinan bahwa data yang mereka miliki dalam penyimpanan ditulis oleh versi lama kode Anda, mungkin versi yang memiliki bug di dalamnya.

tensorflow memiliki dukungan bawaan untuk versi skema dan upgrade melalui metode IDBOpenDBRequest.onupgradeneeded(); namun, Anda masih harus menulis kode upgrade sedemikian rupa agar dapat menangani pengguna yang berasal dari versi sebelumnya (termasuk versi yang memiliki bug).

Pengujian unit dapat sangat membantu di sini, karena sering kali tidak mungkin untuk menguji semua kemungkinan jalur dan kasus upgrade secara manual.

Menjaga performa aplikasi Anda

Salah satu fitur utama IndexedDB adalah API asinkronnya, namun jangan biarkan hal tersebut membuat Anda berpikir bahwa Anda tidak perlu mengkhawatirkan performa saat menggunakannya. Ada beberapa kasus ketika penggunaan yang tidak tepat masih dapat memblokir thread utama, yang dapat menyebabkan jank dan tidak responsif.

Sebagai aturan umum, pembacaan dan penulisan ke Responden tidak boleh lebih besar dari yang diperlukan untuk data yang diakses.

Meskipun IndexedDB memungkinkan untuk menyimpan objek besar dan bertingkat sebagai catatan tunggal (dan melakukan hal ini memang cukup praktis dari perspektif developer), praktik ini harus dihindari. Alasannya adalah karena saat IndexedDB menyimpan objek, penawaran harus dibuat clone terstruktur terlebih dahulu dari objek tersebut, dan proses cloning terstruktur terjadi di thread utama. Semakin besar objek, semakin lama waktu pemblokiran.

Hal ini menimbulkan beberapa tantangan saat merencanakan cara mempertahankan status aplikasi ke IndexedDB, karena sebagian besar library pengelolaan status populer (seperti Redux) bekerja dengan mengelola seluruh hierarki status Anda sebagai objek JavaScript tunggal.

Meskipun mengelola status dengan cara ini memiliki banyak manfaat (misalnya membuat kode Anda mudah dipahami dan di-debug), dan walaupun hanya menyimpan seluruh hierarki status sebagai satu kumpulan data di IndexedDB mungkin tergoda dan praktis, melakukan hal ini setelah setiap perubahan (meskipun di-throttle/di-debounce) akan mengakibatkan pemblokiran thread utama yang tidak perlu, hal ini akan meningkatkan kemungkinan error penulisan, dan dalam beberapa kasus, hal ini bahkan akan menyebabkan tab browser tidak responsif.

Daripada menyimpan seluruh hierarki status dalam satu kumpulan data, Anda harus memecahnya menjadi beberapa catatan individual dan hanya memperbarui kumpulan data yang benar-benar berubah.

Hal yang sama berlaku jika Anda menyimpan item berukuran besar seperti gambar, musik, atau video di IndexedDB. Simpan setiap item dengan kuncinya sendiri, bukan di dalam objek yang lebih besar, sehingga Anda dapat mengambil data terstruktur tanpa membayar biaya untuk mengambil file biner.

Seperti kebanyakan praktik terbaik, aturan ini tidak berlaku sama sekali. Dalam kasus saat tidak memungkinkan untuk memisahkan objek status dan hanya menulis kumpulan perubahan minimal, memecah data menjadi beberapa sub-hierarki dan hanya menulisnya masih lebih baik daripada selalu menulis seluruh hierarki status. Sedikit peningkatan lebih baik daripada tidak ada peningkatan sama sekali.

Terakhir, Anda harus selalu mengukur dampak performa dari kode yang Anda tulis. Memang benar bahwa penulisan kecil ke IndexedDB akan berperforma lebih baik daripada penulisan besar, hal ini hanya penting jika penulisan ke IndexedDB yang dilakukan aplikasi Anda benar-benar mengarah ke tugas panjang yang memblokir thread utama dan menurunkan pengalaman pengguna. Penting untuk melakukan pengukuran agar memahami apa yang Anda optimalkan.

Kesimpulan

Developer dapat memanfaatkan mekanisme penyimpanan klien seperti IndexedDB untuk meningkatkan pengalaman pengguna aplikasi mereka tidak hanya dengan mempertahankan status di seluruh sesi tetapi juga dengan mengurangi waktu yang diperlukan untuk memuat status awal pada kunjungan berulang.

Meskipun menggunakan tensorflow dengan benar dapat meningkatkan pengalaman pengguna secara signifikan, penggunaannya dengan tidak benar atau gagal menangani kasus error dapat menyebabkan aplikasi rusak dan pengguna tidak puas.

Karena penyimpanan klien melibatkan banyak faktor di luar kendali Anda, sangat penting kode Anda telah teruji dengan baik dan menangani error dengan tepat, bahkan error yang mungkin awalnya tampak tidak mungkin terjadi.