Memperkirakan Ruang Penyimpanan yang Tersedia

tl;dr

Chrome 61, dengan lebih banyak browser menyusul, kini menampilkan perkiraan jumlah penyimpanan yang digunakan aplikasi web dan jumlah yang tersedia melalui:

if ('storage' in navigator && 'estimate' in navigator.storage) {
  navigator.storage.estimate().then(({usage, quota}) => {
    console.log(`Using ${usage} out of ${quota} bytes.`);
  });
}

Penyimpanan data dan aplikasi web modern

Saat Anda memikirkan kebutuhan penyimpanan aplikasi web modern, ada baiknya untuk memecah apa yang disimpan ke dalam dua kategori: data inti yang diperlukan untuk memuat aplikasi web, dan data yang diperlukan untuk interaksi pengguna yang bermakna setelah aplikasi dimuat.

Jenis data pertama, yang diperlukan untuk memuat aplikasi web Anda, terdiri dari HTML, JavaScript, CSS, dan mungkin beberapa gambar. Service worker, beserta Cache Storage API, menyediakan infrastruktur yang diperlukan untuk menyimpan resource inti tersebut, lalu menggunakannya di lain waktu untuk memuat aplikasi web Anda dengan cepat, idealnya mengabaikan jaringan sepenuhnya. (Alat yang terintegrasi dengan proses build aplikasi web Anda, seperti library Workbox baru atau sw-precache lama, dapat sepenuhnya mengotomatiskan proses penyimpanan, pembaruan, dan penggunaan jenis data ini.)

Tapi bagaimana dengan jenis data yang lainnya? Resource ini tidak diperlukan untuk memuat aplikasi web Anda, tetapi mungkin memainkan peran penting dalam pengalaman pengguna Anda secara keseluruhan. Misalnya, jika Anda menulis aplikasi web pengeditan gambar, Anda mungkin ingin menyimpan satu atau beberapa salinan lokal suatu gambar, sehingga pengguna dapat beralih di antara revisi dan mengurungkan pekerjaan mereka. Atau, jika Anda mengembangkan pengalaman pemutaran media offline, menyimpan file audio atau video secara lokal akan menjadi fitur penting. Setiap aplikasi web yang dapat dipersonalisasi pada akhirnya perlu menyimpan beberapa semacam informasi status. Bagaimana Anda mengetahui jumlah ruang yang tersedia untuk jenis penyimpanan runtime ini, dan apa yang terjadi jika Anda kehabisan ruang?

Lama: window.webkitStorageInfo dan navigator.webkitTemporaryStorage

Secara historis, browser mendukung jenis introspeksi ini melalui antarmuka berawalan, seperti window.webkitStorageInfo yang sangat lama (dan tidak digunakan lagi), dan navigator.webkitTemporaryStorage yang belum sepenuhnya usang, tetapi masih non-standar. Meskipun antarmuka ini memberikan informasi yang berguna, mereka tidak memiliki masa depan sebagai standar web.

Di sinilah WhatWG Storage Standard mulai memasuki tahap ini.

Masa mendatang: navigator.storage

Sebagai bagian dari pengembangan berkelanjutan pada Storage Living Standard, beberapa API yang berguna telah berhasil mencapai antarmuka StorageManager yang diekspos ke browser sebagai navigator.storage. Seperti banyak API web baru lainnya, navigator.storage hanya tersedia di origin yang aman (disalurkan melalui HTTPS, atau localhost).

Tahun lalu, kami memperkenalkan metode navigator.storage.persist() yang memungkinkan aplikasi web Anda meminta agar penyimpanannya dikecualikan dari pembersihan otomatis.

Sekarang, objek ini digabungkan dengan metode navigator.storage.estimate(), yang berfungsi sebagai pengganti modern untuk navigator.webkitTemporaryStorage.queryUsageAndQuota(). estimate() menampilkan informasi yang serupa, tetapi menampilkan antarmuka berbasis promise, yang sesuai dengan API asinkron modern lainnya. Promise yang ditampilkan estimate() di-resolve dengan objek yang berisi dua properti: usage, yang mewakili jumlah byte yang digunakan saat ini, dan quota, yang menunjukkan byte maksimum yang dapat disimpan oleh origin saat ini. (Seperti semua hal lain yang terkait dengan penyimpanan, kuota diterapkan di seluruh origin.)

Jika aplikasi web mencoba menyimpan, misalnya menggunakan, IndexedDB atau Cache Storage API, data yang cukup besar untuk membawa origin tertentu melebihi kuota yang tersedia, permintaan akan gagal dengan pengecualian QuotaExceededError.

Cara kerja estimasi penyimpanan

Cara Anda menggunakan estimate() bergantung pada jenis data yang perlu disimpan oleh aplikasi Anda. Misalnya, Anda dapat memperbarui kontrol di antarmuka yang memungkinkan pengguna mengetahui jumlah ruang yang digunakan setelah setiap operasi penyimpanan selesai. Idealnya, Anda harus menyediakan antarmuka yang memungkinkan pengguna secara manual membersihkan data yang tidak diperlukan lagi. Anda dapat menulis kode sepanjang baris:

// For a primer on async/await, see
// https://developers.google.com/web/fundamentals/getting-started/primers/async-functions
async function storeDataAndUpdateUI(dataUrl) {
  // Pro-tip: The Cache Storage API is available outside of service workers!
  // See https://googlechrome.github.io/samples/service-worker/window-caches/
  const cache = await caches.open('data-cache');
  await cache.add(dataUrl);

  if ('storage' in navigator && 'estimate' in navigator.storage) {
    const {usage, quota} = await navigator.storage.estimate();
    const percentUsed = Math.round(usage / quota * 100);
    const usageInMib = Math.round(usage / (1024 * 1024));
    const quotaInMib = Math.round(quota / (1024 * 1024));

    const details = `${usageInMib} out of ${quotaInMib} MiB used (${percentUsed}%)`;

    // This assumes there's a <span id="storageEstimate"> or similar on the page.
    document.querySelector('#storageEstimate').innerText = details;
  }
}

Seberapa akurat perkiraannya?

Sulit untuk melewatkan fakta bahwa data yang Anda dapatkan kembali dari fungsi hanyalah perkiraan ruang yang digunakan suatu asal. Itu tepat di bagian nama fungsi. Baik nilai usage maupun quota tidak dimaksudkan agar stabil, jadi sebaiknya pertimbangkan hal-hal berikut:

  • usage menunjukkan jumlah byte yang digunakan secara efektif oleh origin tertentu untuk data origin yang sama, yang kemudian dapat terpengaruh oleh teknik kompresi internal, blok alokasi ukuran tetap yang mungkin mencakup ruang yang tidak digunakan, dan keberadaan data"tombstone" yang mungkin dibuat sementara setelah penghapusan. Untuk mencegah kebocoran informasi ukuran yang tepat, resource buram lintas origin yang disimpan secara lokal dapat berkontribusi pada byte padding tambahan ke keseluruhan nilai usage.
  • quota menunjukkan jumlah ruang yang saat ini dicadangkan untuk origin. Nilainya bergantung pada beberapa faktor konstan seperti ukuran penyimpanan keseluruhan, tetapi juga sejumlah faktor yang berpotensi tidak stabil, termasuk jumlah ruang penyimpanan yang saat ini tidak digunakan. Jadi, saat aplikasi lain di perangkat menulis atau menghapus data, jumlah ruang yang dapat disediakan browser untuk asal aplikasi web Anda kemungkinan akan berubah.

Saat ini: deteksi dan penggantian fitur

estimate() diaktifkan secara default mulai Chrome 61. Firefox sedang bereksperimen dengan navigator.storage, tetapi, mulai Agustus 2017, browser ini tidak diaktifkan secara default. Anda harus mengaktifkan preferensi dom.storageManager.enabled untuk mengujinya.

Saat bekerja dengan fungsi yang belum didukung di semua browser, deteksi fitur adalah suatu keharusan. Anda dapat menggabungkan deteksi fitur bersama dengan wrapper berbasis promise selain metode navigator.webkitTemporaryStorage lama untuk memberikan antarmuka yang konsisten di sepanjang baris:

function storageEstimateWrapper() {
  if ('storage' in navigator && 'estimate' in navigator.storage) {
    // We've got the real thing! Return its response.
    return navigator.storage.estimate();
  }

  if ('webkitTemporaryStorage' in navigator &&
      'queryUsageAndQuota' in navigator.webkitTemporaryStorage) {
    // Return a promise-based wrapper that will follow the expected interface.
    return new Promise(function(resolve, reject) {
      navigator.webkitTemporaryStorage.queryUsageAndQuota(
        function(usage, quota) {resolve({usage: usage, quota: quota})},
        reject
      );
    });
  }

  // If we can't estimate the values, return a Promise that resolves with NaN.
  return Promise.resolve({usage: NaN, quota: NaN});
}