Penyimpanan untuk web

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

Koneksi internet bisa terputus-putus atau tidak ada saat bepergian, itulah sebabnya dukungan offline dan kinerja yang dapat diandalkan adalah fitur umum dalam progressive web app. Bahkan dalam nirkabel yang sempurna keamanan, penggunaan cache yang bijaksana, dan teknik penyimpanan lainnya, dapat secara substansial meningkatkan pengalaman pengguna. 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? Cara apa yang bisa Anda simpan? Bagaimana cara Anda mencegahnya agar tidak dikeluarkan?

Apa yang harus saya gunakan?

Berikut adalah rekomendasi umum untuk menyimpan resource:

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

Bagaimana dengan mekanisme penyimpanan lainnya?

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

SessionStorage bersifat khusus tab, dan tercakup dalam masa aktif tab. Mungkin berguna untuk menyimpan sesi dalam jumlah kecil informasi khusus, misalnya kunci IndexedDB. Ini harus digunakan dengan hati-hati karena bersifat sinkron dan akan memblokir thread utama. Penting dibatasi hingga sekitar 5 MB dan hanya dapat berisi string. Karena ini khusus tab, itu tidak dapat diakses dari pekerja web atau pekerja layanan.

LocalStorage harus dihindari karena bersifat sinkron dan akan memblokir thread utama. Ukurannya dibatasi sekitar 5 MB dan dapat berisi hanya {i>string<i}. LocalStorage tidak dapat diakses dari web worker atau layanan pekerja.

Cookie memiliki kegunaannya sendiri, tetapi tidak boleh digunakan untuk penyimpanan. {i>Cookie<i} dikirim dengan setiap permintaan HTTP, jadi menyimpan apa pun yang lebih dari sedikit data akan meningkatkan ukuran setiap permintaan web secara signifikan. Keduanya bersifat sinkron, dan tidak dapat diakses dari pekerja web. Suka Pada LocalStorage dan SessionStorage, cookie dibatasi hanya untuk string.

File System API dan FileWriter API menyediakan metode untuk membaca dan menulis file ke sistem file dalam {i>sandbox<i}. Meskipun asinkron, hal tersebut tidak disarankan karena hanya tersedia di browser berbasis Chromium.

File System Access API dirancang untuk membuatnya mudah bagi pengguna untuk membaca dan mengedit file di sistem file lokal mereka. Pengguna harus memberikan izin agar halaman dapat membaca atau menulis ke file lokal, dan izin akses tidak dipertahankan di seluruh sesi.

WebSQL tidak boleh digunakan, dan penggunaan yang ada harus dimigrasikan ke tensorflow. Dukungan telah dihapus dari hampir semua perusahaan besar browser. W3C berhenti mempertahankan spesifikasi Web SQL pada tahun 2010, tanpa rencana untuk melakukan pembaruan lebih lanjut yang telah direncanakan.

Cache Aplikasi tidak boleh digunakan, dan penggunaan yang ada harus dimigrasikan ke pekerja layanan dan Cache API. Sudah tidak digunakan lagi dan dukungan akan dihapus dari browser pada masa depan.

Berapa banyak yang dapat saya simpan?

Singkatnya, sangat banyak, setidaknya beberapa ratus megabyte, dan mungkin ratusan gigabita atau lebih. Penerapan browser bervariasi, namun jumlahnya yang tersedia biasanya didasarkan pada jumlah penyimpanan yang tersedia di perangkat seluler.

  • Chrome memungkinkan browser menggunakan hingga 80% dari total ruang disk. Origin dapat akan menggunakan hingga 60% dari total ruang {i>disk<i}. Anda dapat menggunakan layanan StorageManager API untuk menentukan kuota maksimum yang tersedia. Berbasis Chromium lainnya browser tersebut 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 menjadi maksimum sekitar 300 MB.
    • Lihat PR #3896 untuk mengetahui detail tentang implementasi Chrome.
  • Internet Explorer 10 dan yang lebih baru dapat menyimpan hingga 250 MB dan akan meminta pengguna jika telah digunakan lebih dari 10 MB.
  • Firefox memungkinkan browser menggunakan hingga 50% ruang disk kosong. Channel eTLD+1 grup (mis., example.com, www.example.com, dan foo.bar.example.com) dapat menggunakan hingga 2 GB. Anda dapat menggunakan StorageManager API untuk menentukan seberapa banyak ruang penyimpanan yang masih yang tersedia.
  • Safari (desktop dan seluler) tampaknya mengizinkan sekitar 1 GB. Saat batas tercapai, Safari akan meminta pengguna, meningkatkan batas 200 MB tambahan. Saya tidak bisa menemukan dokumentasi resmi terkait hal ini.
    • Jika PWA ditambahkan ke layar utama di Safari seluler, PWA akan muncul membuat penampung penyimpanan baru, dan tidak ada yang dibagikan di antara PWA dan Safari seluler. Setelah kuota untuk PWA terinstal tercapai, tampaknya bukan cara untuk meminta penyimpanan tambahan.

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

Saat ini, sebagian besar browser modern tidak akan meminta izin pengguna, dan akan mengizinkan situs untuk menggunakan hingga kuota yang dialokasikan. Sepertinya pengecualian adalah Safari, yang akan menampilkan dialog ketika kuota penyimpanan terlampaui, meminta izin untuk menambah 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 origin, dan berapa banyak penyimpanan yang digunakannya. Ini melaporkan total jumlah byte yang digunakan oleh IndexedDB dan Cache API, serta memungkinkan untuk menghitung perkiraan ruang penyimpanan yang tersisa 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 implemented di semua browser, sehingga Anda harus fitur deteksi sebelum menggunakannya. Bahkan saat data tersedia, Anda harus masih menangkap error kuota berlebih (lihat di bawah). Dalam beberapa kasus, kuota yang tersedia akan melebihi jumlah penyimpanan aktual yang tersedia.

Periksa

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

Fitur baru telah ditambahkan di Chrome 88 yang memungkinkan Anda mengganti penyimpanan situs kuota di Panel Penyimpanan. Fitur ini memberi Anda kemampuan untuk menyimulasikan perangkat yang berbeda dan menguji perilaku aplikasi Anda pada ketersediaan {i>disk<i} yang rendah yang signifikan. Buka Application lalu Storage, aktifkan Kotak centang Simulasikan kuota penyimpanan kustom, lalu masukkan angka yang valid untuk melakukan simulasi kuota penyimpanan.

Panel Storage DevTools.

Saat mengerjakan artikel ini, saya menulis alat sederhana untuk mencoba menggunakan penyimpanan sebanyak mungkin dengan cepat. Ini adalah cara yang cepat dan mudah untuk bereksperimen dengan mekanisme penyimpanan yang berbeda, dan melihat apa yang terjadi ketika Anda menggunakan semua kuota.

Bagaimana cara menangani masalah kuota yang berlebih?

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

Baik BYOD dan Cache API menampilkan DOMError yang bernama QuotaExceededError saat Anda telah melebihi kuota yang tersedia.

IndexedDB

Jika origin telah melampaui kuota, upaya untuk menulis ke IndexedDB akan gagal. Pengendali onabort() transaksi akan dipanggil, dengan meneruskan peristiwa. Peristiwa ini 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, upayakan untuk menulis ke Cache API akan menolak 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 penghapusan?

Penyimpanan web dikategorikan ke dalam dua kategori, "Upaya Terbaik" dan "Persisten". Upaya terbaik berarti penyimpanan dapat dikosongkan oleh browser tanpa mengganggu pengguna, tetapi kurang tahan lama untuk data jangka panjang atau data penting. Penyimpanan persisten tidak otomatis dihapus saat penyimpanan tinggal sedikit. 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 sebuah situs memiliki 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, membersihkan semua data situs dari sumber yang paling jarang digunakan terlebih dahulu, lalu berikutnya, sampai {i>browser<i} tidak lagi melebihi batas.
  • Internet Explorer 10+ tidak akan mengeluarkan data, namun akan mencegah origin dari menulis lagi.
  • Firefox akan mulai mengeluarkan data saat ruang {i>disk<i} yang tersedia terisi, menghapus semua data situs dari asal yang paling jarang digunakan terlebih dahulu, lalu selanjutnya, hingga browser tidak lagi melebihi batas.
  • Safari sebelumnya tidak mengeluarkan data, tetapi baru-baru ini menerapkan batas tujuh hari pada semua penyimpanan yang dapat ditulis (lihat di bawah).

Mulai dari iOS dan iPadOS 13.4 serta Safari 13.1 di macOS, ada batas tujuh hari pada semua penyimpanan yang dapat ditulis untuk skrip, termasuk IndexedDB, layanan pendaftaran pekerja, dan Cache API. Ini berarti Safari akan menghapus semua konten dari {i>cache<i} setelah Safari tujuh hari digunakan jika pengguna tidak berinteraksi dengan situs. Kebijakan penghapusan ini tidak berlaku untuk PWA yang telah ditambahkan ke layar utama. Lihat Pemblokiran Cookie Pihak Ketiga Penuh dan Lainnya di WebKit untuk detail selengkapnya.

Bonus: Mengapa menggunakan wrapper untuk IndexedDB

StrictMode adalah API tingkat rendah yang memerlukan penyiapan yang signifikan sebelum digunakan, yang bisa sangat menyakitkan untuk menyimpan data sederhana. Tidak seperti kebanyakan modern berbasis promise, berbasis peristiwa. Wrapper promise seperti idb untuk IndexedDB menyembunyikan beberapa fitur canggih namun lebih yang penting, sembunyikan mesin yang kompleks (misalnya transaksi, pembuatan versi skema) yang dilengkapi dengan library IndexedDB.

Kesimpulan

Anda tidak akan lagi memerlukan penyimpanan terbatas dan mengharuskan pengguna untuk menyimpan lebih banyak lebih banyak data. Situs dapat secara efektif menyimpan semua sumber daya dan data yang yang perlu dijalankan. Dengan StorageManager API, Anda dapat menentukan berapa banyak yang tersedia bagi Anda, dan berapa banyak yang telah Anda gunakan. Dengan penyimpanan persisten, kecuali jika pengguna menghapusnya, Anda dapat melindunginya dari penghapusan.

Referensi lainnya

Terima kasih

Terima kasih khusus kepada Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink, dan Victor Costan untuk mengulas artikel ini. Terima kasih kepada Eiji Kitamura, Addy Osmani, dan Marc Cohen yang menulis artikel asli yang menjadi dasarnya. Eiji menulis alat yang berguna yang disebut Browser Storage Abuser yang berguna dalam memvalidasi perilaku saat ini. Hal ini memungkinkan Anda untuk menyimpan data sebanyak mungkin dan melihat batas penyimpanan di browser Anda. Terima kasih kepada Francois Beaufort yang telah melakukan penelitian ke Safari untuk mengetahui batas penyimpanannya.

Gambar utama itu ditulis oleh Guillaume Bolduc di Buka Percikan.