Penyimpanan untuk web

Ada banyak opsi untuk menyimpan data di browser. Mana yang paling sesuai dengan kebutuhan Anda?

Koneksi internet bisa berubah-ubah atau tidak ada kapan saja di mana saja. Itulah sebabnya dukungan offline dan performa yang andal merupakan fitur umum di progressive web app. Bahkan di lingkungan nirkabel yang sempurna, penggunaan cache dan teknik penyimpanan lainnya yang bijaksana dapat meningkatkan pengalaman pengguna secara signifikan. Ada beberapa cara untuk meng-cache resource aplikasi statis (HTML, JavaScript, CSS, gambar, dll.), dan data (data pengguna, artikel berita, dll.). Namun, manakah solusi terbaik? Seberapa banyak yang dapat Anda simpan? Bagaimana Anda mencegahnya agar tidak dikeluarkan?

Apa yang harus saya gunakan?

Berikut adalah rekomendasi umum untuk menyimpan resource:

IndexedDB dan Cache Storage API didukung di setiap browser modern. Keduanya bersifat asinkron, dan tidak akan memblokir thread utama. Keduanya dapat diakses dari objek window, pekerja web, dan pekerja layanan, sehingga mudah digunakan di mana saja dalam kode Anda.

Bagaimana dengan mekanisme penyimpanan lainnya?

Ada beberapa mekanisme penyimpanan lain yang tersedia di browser, tetapi penggunaannya terbatas dan dapat menyebabkan masalah performa yang signifikan.

SessionStorage adalah tab khusus, dan dicakupkan ke masa aktif tab. Ini mungkin berguna untuk menyimpan sejumlah kecil informasi khusus sesi, misalnya kunci IndexedDB. Metode ini harus digunakan dengan hati-hati karena bersifat sinkron dan akan memblokir thread utama. File ini dibatasi maksimal 5 MB dan hanya dapat berisi string. Karena bersifat khusus tab, ini tidak dapat diakses dari pekerja web atau pekerja layanan.

LocalStorage harus dihindari karena bersifat sinkron dan akan memblokir thread utama. Ukurannya terbatas sekitar 5 MB dan hanya dapat berisi string. LocalStorage tidak dapat diakses dari pekerja web atau pekerja layanan.

Cookie memiliki kegunaannya sendiri, tetapi tidak boleh digunakan untuk penyimpanan. Cookie dikirim dengan setiap permintaan HTTP, sehingga menyimpan data apa pun yang lebih dari sejumlah kecil akan meningkatkan ukuran setiap permintaan web secara signifikan. Metode ini sinkron, dan tidak dapat diakses dari pekerja web. Seperti LocalStorage dan SessionStorage, cookie dibatasi hanya untuk string.

File System API dan FileWriter API menyediakan metode untuk membaca dan menulis file ke sistem file dengan sandbox. Meskipun asinkron, proses ini tidak direkomendasikan karena hanya tersedia di browser berbasis Chromium.

File System Access API dirancang untuk memudahkan pengguna membaca dan mengedit file di sistem file lokal mereka. Pengguna harus memberikan izin sebelum halaman dapat membaca atau menulis ke file lokal apa pun, dan izin tidak akan dipertahankan di seluruh sesi.

WebSQL tidak boleh digunakan, dan penggunaan yang sudah ada harus dimigrasikan ke IndexedDB. Dukungan telah dihapus dari hampir semua browser utama. W3C berhenti mempertahankan spesifikasi Web SQL pada tahun 2010, tanpa rencana pembaruan lebih lanjut.

Cache aplikasi tidak boleh digunakan, dan penggunaan yang sudah ada harus dimigrasikan ke pekerja layanan dan Cache API. Fitur ini tidak digunakan lagi dan dukungan akan dihapus dari browser pada masa mendatang.

Berapa banyak yang dapat saya simpan?

Singkatnya, banyak, setidaknya beberapa ratus megabyte, dan mungkin ratusan gigabyte atau lebih. Implementasi browser bervariasi, tetapi jumlah penyimpanan yang tersedia biasanya didasarkan pada jumlah penyimpanan yang tersedia di perangkat.

  • Chrome memungkinkan browser menggunakan hingga 80% total kapasitas disk. Asal dapat menggunakan hingga 60% dari total ruang disk. Anda dapat menggunakan StorageManager API untuk menentukan kuota maksimum yang tersedia. Browser berbasis Chromium lainnya mungkin berbeda.
    • Dalam mode samaran, Chrome mengurangi jumlah penyimpanan yang dapat digunakan origin hingga sekitar 5% dari total ruang disk.
    • Jika pengguna telah mengaktifkan "Hapus cookie dan data situs saat Anda menutup semua jendela" di Chrome, kuota penyimpanan akan dikurangi secara signifikan hingga maksimum sekitar 300 MB.
    • Lihat PR #3896 untuk mengetahui detail implementasi Chrome.
  • Internet Explorer 10 dan yang lebih baru dapat menyimpan hingga 250 MB dan akan meminta pengguna jika telah menggunakan lebih dari 10 MB.
  • Firefox memungkinkan browser menggunakan hingga 50% dari kapasitas disk yang tersedia. Grup eTLD+1 (misalnya, example.com, www.example.com, dan foo.bar.example.com) dapat menggunakan hingga 2 GB. Anda dapat menggunakan StorageManager API untuk menentukan jumlah ruang yang masih tersedia.
  • Safari (desktop dan seluler) tampaknya mengizinkan sekitar 1 GB. Saat batas ini tercapai, Safari akan meminta pengguna untuk meningkatkan batas dalam penambahan 200 MB. Saya tidak bisa menemukan dokumentasi resmi tentang hal ini.
    • Jika PWA ditambahkan ke layar utama di Safari seluler, PWA akan muncul untuk membuat penampung penyimpanan baru, dan tidak ada yang dibagikan antara PWA dan Safari seluler. Setelah kuota untuk PWA yang diinstal tercapai, tampaknya tidak ada cara untuk meminta penyimpanan tambahan.

Di masa lalu, jika situs melampaui batas data yang disimpan tertentu, browser akan meminta pengguna memberikan izin untuk menggunakan lebih banyak data. Misalnya, jika origin menggunakan lebih dari 50 MB, browser akan meminta pengguna untuk mengizinkannya menyimpan hingga 100 MB, lalu meminta lagi saat kelipatan 50 MB.

Saat ini, sebagian besar browser modern tidak akan meminta izin pengguna, dan akan memungkinkan situs menggunakan kuota yang ditentukan. Pengecualiannya adalah Safari, yang akan meminta izin saat kuota penyimpanan terlampaui, dan meminta izin untuk meningkatkan kuota yang dialokasikan. Jika origin mencoba menggunakan lebih dari kuota yang dialokasikan, upaya lebih lanjut untuk menulis data akan gagal.

Bagaimana cara memeriksa jumlah penyimpanan yang tersedia?

Di banyak browser, Anda dapat menggunakan StorageManager API untuk menentukan jumlah penyimpanan yang tersedia untuk asal, dan berapa banyak penyimpanan yang digunakan. API ini melaporkan total jumlah byte yang digunakan oleh IndexedDB dan Cache API, serta memungkinkan penghitungan sisa ruang penyimpanan yang tersedia.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

StorageManager belum diimplementasikan di semua browser, jadi Anda harus mendeteksinya terlebih dahulu sebelum menggunakannya. Meskipun tersedia, Anda tetap harus menangkap error kelebihan kuota (lihat di bawah). Dalam beberapa kasus, kuota yang tersedia dapat melebihi jumlah penyimpanan sebenarnya yang tersedia.

Periksa

Selama pengembangan, Anda dapat menggunakan DevTools browser untuk memeriksa berbagai jenis penyimpanan, dan menghapus semua data yang tersimpan dengan mudah.

Fitur baru telah ditambahkan di Chrome 88 yang memungkinkan Anda mengganti kuota penyimpanan situs di Panel Penyimpanan. Fitur ini memberi Anda kemampuan untuk menyimulasikan berbagai perangkat dan menguji perilaku aplikasi Anda dalam skenario ketersediaan disk yang rendah. Buka Application lalu Storage, aktifkan kotak centang Simulasikan kuota penyimpanan kustom, lalu masukkan angka yang valid untuk menyimulasikan kuota penyimpanan.

Panel Storage DevTools.

Selagi mengerjakan artikel ini, saya menulis alat sederhana untuk mencoba menggunakan penyimpanan sebanyak mungkin dengan cepat. Ini adalah cara cepat dan mudah untuk bereksperimen dengan berbagai mekanisme penyimpanan, serta melihat apa yang terjadi jika seluruh kuota Anda habis.

Bagaimana cara menangani kelebihan kuota?

Apa yang harus Anda lakukan jika melebihi kuota? Yang terpenting, Anda harus selalu menangkap dan menangani error penulisan, baik yang berupa QuotaExceededError maupun yang lainnya. Kemudian, tergantung pada desain aplikasi Anda, putuskan bagaimana cara menanganinya. Misalnya, hapus konten yang sudah lama tidak diakses, hapus data berdasarkan ukuran, atau berikan cara bagi pengguna untuk memilih apa yang ingin mereka hapus.

IndexedDB dan Cache API akan menampilkan DOMError yang bernama QuotaExceededError jika Anda telah melebihi kuota yang tersedia.

IndexedDB

Jika origin telah melampaui kuotanya, upaya menulis ke IndexedDB akan gagal. Pengendali onabort() transaksi akan dipanggil, dengan meneruskan peristiwa. Peristiwa tersebut akan menyertakan DOMException di properti error. Memeriksa error name akan menampilkan QuotaExceededError.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

API Cache

Jika origin telah melampaui kuotanya, upaya untuk menulis ke Cache API akan ditolak dengan QuotaExceededError DOMException.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

Bagaimana cara kerja penggusuran?

Penyimpanan web dikategorikan menjadi dua bucket, "Best Effort" dan "Persistent". Upaya terbaik berarti penyimpanan dapat dikosongkan oleh browser tanpa mengganggu pengguna, tetapi kurang tahan lama untuk data jangka panjang atau penting. Penyimpanan persisten tidak otomatis dihapus saat penyimpanan rendah. Pengguna perlu menghapus penyimpanan ini secara manual (melalui setelan browser).

Secara default, data situs (termasuk IndexedDB, Cache API, dll.) termasuk dalam kategori upaya terbaik, yang berarti kecuali jika situs telah meminta penyimpanan persisten, browser dapat mengeluarkan data situs atas pertimbangannya sendiri, misalnya, saat penyimpanan perangkat hampir penuh.

Kebijakan penghapusan untuk upaya terbaik adalah:

  • Browser berbasis Chromium akan mulai mengeluarkan data saat browser kehabisan ruang, yang akan menghapus semua data situs dari origin yang paling lama tidak digunakan terlebih dahulu, lalu yang berikutnya, hingga browser tidak lagi melebihi batas.
  • Internet Explorer 10+ tidak akan menghapus data, tetapi akan mencegah origin menulis lagi.
  • Firefox akan mulai mengeluarkan data jika kapasitas disk yang tersedia terisi, menghapus semua data situs dari asal yang paling lama tidak digunakan terlebih dahulu, lalu selanjutnya, hingga browser tidak lagi melebihi batas.
  • Safari sebelumnya tidak mengeluarkan data, namun baru-baru ini menerapkan batas baru tujuh hari untuk semua penyimpanan yang dapat ditulis (lihat di bawah).

Mulai iOS dan iPadOS 13.4 dan Safari 13.1 di macOS, ada batas tujuh hari untuk semua penyimpanan skrip yang dapat ditulis, termasuk IndexedDB, pendaftaran pekerja layanan, dan Cache API. Artinya, Safari akan mengeluarkan semua konten dari cache setelah tujuh hari menggunakan Safari jika pengguna tidak berinteraksi dengan situs. Kebijakan penghapusan ini tidak berlaku untuk PWA terinstal yang telah ditambahkan ke layar utama. Lihat Pemblokiran Cookie Pihak Ketiga Lengkap dan Selengkapnya di blog WebKit untuk detail selengkapnya.

Bonus: Mengapa menggunakan wrapper untuk IndexedDB

IndexedDB adalah API tingkat rendah yang memerlukan penyiapan signifikan sebelum digunakan, yang dapat sangat menyulitkan untuk menyimpan data sederhana. Tidak seperti kebanyakan API modern berbasis promise, API ini berbasis peristiwa. Wrapper Promise seperti idb untuk IndexedDB menyembunyikan beberapa fitur canggih, tetapi yang lebih penting, menyembunyikan mesin kompleks (misalnya transaksi, pembuatan versi skema) yang disertakan dengan library IndexedDB.

Kesimpulan

Anda tidak akan lagi mendapati penyimpanan terbatas dan mengharuskan pengguna untuk menyimpan lebih banyak data. Situs dapat menyimpan secara efektif semua resource dan data yang perlu dijalankan. Dengan StorageManager API, Anda dapat menentukan seberapa banyak yang tersedia untuk Anda dan seberapa banyak yang telah digunakan. Dan dengan penyimpanan persisten, Anda dapat melindunginya dari penghapusan kecuali jika pengguna menghapusnya.

Referensi tambahan

Terima kasih

Terima kasih khusus kepada Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijin Kruisselbrink, dan Victor Costan karena telah meninjau artikel ini. Terima kasih kepada Eiji Kitamura, Addy Osmani, dan Marc Cohen yang menulis artikel asli yang menjadi dasar penulisan ini. Eiji menulis alat bermanfaat yang disebut Browser Storage Abuser yang berguna dalam memvalidasi perilaku saat ini. Anda dapat menyimpan data sebanyak mungkin dan melihat batas penyimpanan di browser. Terima kasih kepada Francois Beaufort yang telah mempelajari Safari untuk mengetahui batas penyimpanannya.

Banner besarnya adalah oleh Guillaume Bolduc di Unsplash.