Ada berbagai opsi untuk menyimpan data di browser. Mana yang paling sesuai dengan kebutuhan Anda?
Koneksi internet bisa saja tidak stabil atau tidak ada saat dalam perjalanan, itulah sebabnya dukungan offline dan performa yang andal adalah fitur umum dalam progressive web app. Bahkan di lingkungan nirkabel yang sempurna, penggunaan caching dan teknik penyimpanan lainnya secara 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? Berapa banyak yang dapat Anda simpan? Bagaimana cara mencegahnya agar tidak dikeluarkan?
Apa yang harus saya gunakan?
Berikut rekomendasi umum untuk menyimpan resource:
- Untuk resource jaringan yang diperlukan untuk memuat aplikasi Anda, gunakan Cache Storage API (bagian dari service worker).
- Untuk konten berbasis file, gunakan Origin Private File System (OPFS).
- Untuk data lainnya, gunakan IndexedDB (dengan wrapper promise).
IndexedDB, OPFS, dan Cache Storage API didukung di setiap browser modern.
API ini bersifat asinkron, dan tidak akan memblokir thread utama (tetapi ada juga varian sinkron
OPFS yang tersedia secara eksklusif di web worker). API ini dapat diakses dari objek window, web worker, dan pekerja layanan, sehingga dapat 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 bersifat spesifik per tab, dan dicakup ke masa aktif tab. Hal 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. Penyimpanan ini dibatasi hingga sekitar 5 MB dan hanya dapat berisi string. Karena bersifat khusus tab, API ini tidak dapat diakses dari web worker atau pekerja layanan.
LocalStorage harus dihindari karena bersifat sinkron dan akan memblokir thread utama. Penyimpanan ini dibatasi hingga sekitar 5 MB dan hanya dapat berisi string. LocalStorage tidak dapat diakses dari web worker atau service worker.
Cookie memiliki kegunaannya, tetapi tidak boleh digunakan untuk penyimpanan. Cookie dikirim dengan setiap permintaan HTTP, sehingga menyimpan data dalam jumlah yang lebih besar dari jumlah kecil akan meningkatkan ukuran setiap permintaan web secara signifikan. API ini bersifat sinkron, dan tidak dapat diakses dari web worker. Seperti LocalStorage dan SessionStorage, cookie hanya dibatasi untuk string.
File System Access API dirancang untuk memungkinkan 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 dipertahankan di seluruh sesi, kecuali jika handle file di-cache di IndexedDB. File System Access API paling cocok untuk kasus penggunaan seperti editor, tempat Anda perlu membuka file, mengubahnya, lalu mungkin menyimpan kembali perubahan ke file.
File System API dan FileWriter API menyediakan metode untuk membaca dan menulis file ke sistem file dengan sandbox. Meskipun asinkron, metode ini tidak direkomendasikan karena hanya tersedia di browser berbasis Chromium.
Berapa banyak yang dapat saya simpan?
Singkatnya, banyak, setidaknya beberapa ratus megabyte, dan berpotensi 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% dari total kapasitas disk. Origin dapat menggunakan hingga 60% dari total kapasitas 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 oleh origin menjadi sekitar 5% dari total kapasitas disk.
- Jika pengguna telah mengaktifkan "Hapus cookie dan data situs saat Anda menutup semua jendela" di Chrome, kuota penyimpanan akan berkurang secara signifikan hingga maksimum sekitar 300 MB.
- Firefox mengizinkan browser menggunakan hingga 50% kapasitas disk yang tersedia. Grup
eTLD+1
(misalnya,
example.com,www.example.com, danfoo.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
tercapai, Safari akan meminta pengguna, meningkatkan batas dalam kelipatan
200 MB. Saya tidak dapat menemukan dokumentasi resmi tentang hal ini.
- Jika PWA ditambahkan ke layar utama di Safari seluler, PWA akan 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.
Sebelumnya, jika situs melebihi batas tertentu dari penyimpanan data, browser akan meminta pengguna untuk memberikan izin agar dapat 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 dengan penambahan 50 MB.
Saat ini, sebagian besar browser modern tidak akan meminta pengguna, dan akan mengizinkan situs menggunakan hingga kuota yang dialokasikan. Pengecualiannya tampaknya adalah Safari, yang meminta izin untuk meningkatkan kuota alokasi saat kuota penyimpanan terlampaui. 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 jumlah penyimpanan yang digunakannya. API ini melaporkan jumlah total byte yang digunakan oleh IndexedDB dan Cache API, serta memungkinkan penghitungan perkiraan 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.`);
}
Anda harus menangkap error kelebihan kuota (lihat di bawah). Dalam beberapa kasus, kuota yang tersedia mungkin melebihi jumlah penyimpanan yang sebenarnya tersedia.
Periksa
Selama pengembangan, Anda dapat menggunakan DevTools browser untuk memeriksa berbagai jenis penyimpanan, dan menghapus semua data yang disimpan.
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 dalam skenario ketersediaan disk yang rendah. Buka Application, lalu Storage, aktifkan kotak centang Simulate custom storage quota, dan masukkan angka yang valid untuk menyimulasikan kuota penyimpanan.
Bagaimana cara menangani penggunaan yang melebihi kuota?
Apa yang harus Anda lakukan jika melebihi kuota? Yang terpenting, Anda harus selalu menangkap dan menangani error penulisan, baik itu QuotaExceededError maupun hal lainnya. Kemudian, bergantung pada desain aplikasi Anda, tentukan 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 menampilkan DOMError bernama
QuotaExceededError saat Anda melebihi kuota yang tersedia.
IndexedDB
Jika origin telah melebihi kuotanya, upaya untuk menulis ke IndexedDB akan gagal. Pengendali onabort() transaksi akan dipanggil, yang meneruskan peristiwa.
Peristiwa 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
}
};
Cache API
Jika origin telah melebihi 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 pengeluaran?
Penyimpanan web dikategorikan ke dalam dua kelompok, "Upaya Terbaik" dan "Persisten". Upaya terbaik berarti penyimpanan dapat dihapus oleh browser tanpa mengganggu pengguna, tetapi kurang tahan lama untuk data jangka panjang atau penting. Penyimpanan persisten tidak otomatis dihapus saat penyimpanan hampir habis. Pengguna harus 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 menghapus data situs sesuai kebijakannya, misalnya, saat penyimpanan perangkat hampir habis.
Kebijakan penghapusan untuk upaya terbaik adalah:
- Browser berbasis Chromium akan mulai menghapus data saat browser kehabisan ruang, menghapus semua data situs dari origin yang paling jarang digunakan terlebih dahulu, lalu yang berikutnya, hingga browser tidak lagi melebihi batas.
- Firefox akan mulai menghapus data saat kapasitas disk yang tersedia sudah penuh, menghapus semua data situs dari origin yang paling jarang digunakan terlebih dahulu, lalu berikutnya, hingga browser tidak lagi melebihi batas.
- Safari sebelumnya tidak menghapus data, tetapi baru-baru ini menerapkan batas baru tujuh hari untuk semua penyimpanan yang dapat ditulis (lihat di bawah).
Mulai iOS dan iPadOS 13.4 serta Safari 13.1 di macOS, ada batas tujuh hari untuk semua penyimpanan yang dapat ditulis skrip, termasuk IndexedDB, pendaftaran pekerja layanan, dan Cache API. Artinya, Safari akan menghapus semua konten dari cache setelah tujuh hari penggunaan 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 Penuh dan Lainnya di blog WebKit untuk mengetahui detail selengkapnya.
Bucket penyimpanan
Ide inti dari Storage Buckets API adalah memberi situs kemampuan untuk membuat beberapa bucket penyimpanan, yang memungkinkan browser memilih untuk menghapus setiap bucket secara independen dari bucket lainnya. Hal ini memungkinkan developer menentukan prioritas penghapusan untuk memastikan data yang paling berharga tidak dihapus.
Bonus: Alasan menggunakan wrapper untuk IndexedDB
IndexedDB adalah API tingkat rendah yang memerlukan penyiapan signifikan sebelum digunakan, yang dapat sangat menyulitkan untuk menyimpan data dengan kompleksitas rendah. Tidak seperti kebanyakan API berbasis promise modern, API ini berbasis peristiwa. Wrapper promise seperti idb untuk IndexedDB menyembunyikan beberapa fitur canggih, tetapi yang lebih penting, menyembunyikan mekanisme yang kompleks (misalnya, transaksi, pembuatan versi skema) yang disertakan dengan library IndexedDB.
Bonus: SQLite Wasm
Setelah Web SQL tidak digunakan lagi dan dihapus dari Chrome, Google bekerja sama dengan pengelola database SQLite yang populer untuk menawarkan pengganti Web SQL berbasis SQLite. Baca SQLite Wasm di browser yang didukung oleh Origin Private File System untuk mengetahui detail tentang cara menggunakannya.
Kesimpulan
Masa-masa penyimpanan terbatas dan meminta pengguna untuk menyimpan lebih banyak data sudah berlalu. Situs dapat menyimpan semua resource dan data yang diperlukan untuk dijalankan secara efektif. Dengan menggunakan StorageManager API, Anda dapat menentukan berapa banyak penyimpanan yang tersedia untuk Anda, dan berapa banyak yang telah Anda gunakan. Dan dengan penyimpanan persisten, kecuali jika pengguna menghapusnya, Anda dapat melindunginya dari pengosongan.
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 karena telah meninjau panduan ini. Terima kasih kepada Eiji Kitamura, Addy Osmani, dan Marc Cohen yang menulis artikel asli yang menjadi dasar artikel ini. Eiji menulis alat yang berguna bernama Browser Storage Abuser yang berguna dalam memvalidasi perilaku saat ini. Dengan begitu, Anda dapat menyimpan data sebanyak mungkin dan melihat batas penyimpanan di browser Anda. Terima kasih kepada François Beaufort yang telah melakukan penggalian di Safari untuk mengetahui batas penyimpanannya dan kepada Thomas Steiner yang telah menambahkan informasi tentang sistem file pribadi origin, bucket penyimpanan, SQLite Wasm, dan pembaruan konten secara keseluruhan pada tahun 2024.