Memperkirakan Ruang Penyimpanan yang Tersedia

tl;dr

Chrome 61, dengan lebih banyak browser menyusul, kini menampilkan perkiraan seberapa banyak penyimpanan yang digunakan aplikasi web dan berapa banyak 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

Ketika Anda memikirkan tentang kebutuhan penyimpanan aplikasi web modern, ada baiknya bagi apa yang disimpan menjadi dua kategori: data inti yang perlu dimuat aplikasi web, dan data yang dibutuhkan untuk interaksi pengguna yang bermakna sekali 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 dibutuhkan untuk menyimpan sumber daya inti tersebut dan kemudian menggunakan nanti untuk memuat aplikasi web Anda dengan cepat, idealnya melewati jaringan sepenuhnya. (Alat yang terintegrasi dengan proses build aplikasi web Anda, seperti Workbox atau versi lama sw-precache, dapat sepenuhnya mengotomatiskan proses penyimpanan, pembaruan, dan penggunaan jenis data.)

Tapi bagaimana dengan jenis data yang lainnya? Ini adalah sumber daya yang tidak diperlukan untuk memuat aplikasi web Anda, tetapi yang mungkin memainkan peran penting terhadap keseluruhan pengguna pengalaman yang lancar bagi developer. 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 membatalkan pekerjaan mereka. Atau jika Anda mengembangkan media offline pengalaman pemutaran, menyimpan file audio atau video secara lokal akan menjadi hal yang penting aplikasi baru. Setiap aplikasi web yang dapat dipersonalisasi akhirnya perlu menghemat sebagian semacam informasi status. Bagaimana Anda mengetahui berapa banyak ruang yang tersedia untuk jenis penyimpanan {i>runtime<i} ini, dan apa yang terjadi ketika Anda kehabisan ruang penyimpanan?

Lama: window.webkitStorageInfo dan navigator.webkitTemporaryStorage

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

Dari situlah WhatWG Storage Standard masuk ke dalam gambar.

Masa mendatang: navigator.storage

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

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

Sekarang, objek ini digabungkan dengan metode navigator.storage.estimate(), yang berfungsi sebagai pengganti yang modern untuk navigator.webkitTemporaryStorage.queryUsageAndQuota(). estimate() menampilkan informasi yang serupa, tetapi mengekspos berbasis janji, yang sesuai dengan API asinkron modern lainnya. Janji bahwa estimate() menampilkan penyelesaian dengan objek yang berisi dua properti: usage, yang merepresentasikan jumlah byte yang saat ini digunakan, dan quota, yang merepresentasikan byte maksimum yang dapat disimpan oleh perintah origin. (Seperti semua hal lain yang terkait dengan penyimpanan, kuota diterapkan ke seluruh origin.)

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

Cara kerja estimasi penyimpanan

Cara Anda menggunakan estimate() bergantung pada jenis data yang diperlukan aplikasi Anda Anda. Misalnya, Anda dapat memperbarui kontrol di antarmuka Anda yang memungkinkan pengguna mengetahui berapa banyak ruang yang digunakan setelah setiap operasi penyimpanan selesai. Idealnya, Anda akan menyediakan antarmuka yang memungkinkan pengguna membersihkan data secara manual yang tidak lagi diperlukan. 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 hanya perkiraan ruang yang digunakan suatu asal. Itu tepat di {i>function<i} nama! Baik nilai usage maupun quota tidak dimaksudkan agar stabil, jadi sebaiknya Anda mempertimbangkan hal berikut:

  • usage mencerminkan jumlah byte yang digunakan secara efektif oleh origin tertentu untuk origin yang sama data, yang kemudian dapat dipengaruhi oleh teknik kompresi internal, blok alokasi ukuran tetap yang mungkin mencakup ruang yang tidak digunakan, dan keberadaan dari "tombstone" data yang mungkin dibuat untuk sementara setelah penghapusan. Untuk mencegah kebocoran informasi ukuran yang tepat, lintas origin, resource buram yang disimpan secara lokal dapat berkontribusi pada byte padding tambahan untuk keseluruhan usage dengan sejumlah nilai.
  • quota menunjukkan jumlah ruang yang saat ini dicadangkan untuk origin. Tujuan nilai tergantung pada beberapa faktor konstan seperti ukuran penyimpanan secara keseluruhan, tetapi juga jumlah 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 web Anda origin aplikasi kemungkinan akan berubah.

Saat ini: deteksi dan penggantian fitur

estimate() diaktifkan secara default mulai Chrome 61. Firefox adalah bereksperimen dengan navigator.storage, namun, mulai Agustus 2017, aktif secara default. Anda harus aktifkan preferensi dom.storageManager.enabled untuk mengujinya.

Saat bekerja dengan fungsi yang belum didukung di semua {i>browser<i}, deteksi fitur adalah suatu keharusan. Anda dapat menggabungkan deteksi fitur bersama dengan wrapper berbasis promise di atas navigator.webkitTemporaryStorage lama metode untuk menyediakan antarmuka yang konsisten di sepanjang:

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});
}