вр; доктор
Chrome 61, за которым последуют другие браузеры, теперь предоставляет оценку того, сколько памяти использует веб-приложение и сколько доступно через:
if ('storage' in navigator && 'estimate' in navigator.storage) { navigator.storage.estimate().then(({usage, quota}) => { console.log(`Using ${usage} out of ${quota} bytes.`); }); } Современные веб-приложения и хранилище данных
Когда вы думаете о потребностях современного веб-приложения в хранилище, это помогает разбить то, что хранится, на две категории: основные данные, необходимые для загрузки веб-приложения, и данные, необходимые для значимого взаимодействия с пользователем после загрузки приложения.
Первый тип данных, необходимый для загрузки вашего веб-приложения, состоит из HTML, JavaScript, CSS и, возможно, некоторых изображений. Сервис-воркеры вместе с Cache Storage API предоставляют необходимую инфраструктуру для сохранения этих основных ресурсов и последующего использования их для быстрой загрузки вашего веб-приложения, в идеале полностью минуя сеть. (Инструменты, которые интегрируются с процессом сборки вашего веб-приложения, такие как новые библиотеки Workbox или более старая версия sw-precache , могут полностью автоматизировать процесс хранения, обновления и использования данных этого типа.)
А как насчет другого типа данных? Это ресурсы, которые не нужны для загрузки вашего веб-приложения, но могут сыграть решающую роль в общем взаимодействии с пользователем. Например, если вы пишете веб-приложение для редактирования изображений, вам может потребоваться сохранить одну или несколько локальных копий изображения, чтобы пользователи могли переключаться между редакциями и отменять свою работу. Или, если вы разрабатываете автономное воспроизведение мультимедиа, сохранение аудио- или видеофайлов локально будет критически важной функцией. Каждое веб-приложение, которое можно персонализировать, в конечном итоге должно сохранять некоторую информацию о состоянии . Как узнать, сколько места доступно для такого типа хранилища среды выполнения и что произойдет, когда место закончится?
Прошлое: window.webkitStorageInfo и navigator.webkitTemporaryStorage
Браузеры исторически поддерживали этот тип самоанализа через префиксные интерфейсы, такие как очень старый (и устаревший) window.webkitStorageInfo и не совсем старый, но все же нестандартный navigator.webkitTemporaryStorage . Хотя эти интерфейсы предоставляют полезную информацию, у них нет будущего в качестве веб-стандартов.
Именно здесь на сцену выходит стандарт хранения данных WHATWG .
Будущее: navigator.storage
В рамках продолжающейся работы над Storage Living Standard несколько полезных API были добавлены в интерфейс StorageManager , который доступен браузерам как navigator.storage . Как и многие другие новые веб-API, navigator.storage доступен только в защищенных источниках (обслуживаемых через HTTPS или локальный хост).
В прошлом году мы представили метод navigator.storage.persist() , который позволяет вашему веб-приложению запрашивать освобождение его хранилища от автоматической очистки.
Теперь к нему присоединился метод navigator.storage.estimate() , который служит современной заменой navigator.webkitTemporaryStorage.queryUsageAndQuota() . estimate() возвращает аналогичную информацию, но предоставляет интерфейс на основе обещаний , который соответствует другим современным асинхронным API. Обещание, которое возвращает estimate() разрешается с помощью объекта, содержащего два свойства: usage , представляющее количество используемых в данный момент байтов, и quota , представляющее максимальное количество байтов, которые могут быть сохранены текущим источником . (Как и все остальное, что связано с хранилищем, квота применяется ко всему источнику.)
Если веб-приложение попытается сохранить (с помощью, например, IndexedDB или Cache Storage API) данные, достаточно большие для того, чтобы данный источник превысил доступную квоту, запрос завершится ошибкой с исключением QuotaExceededError .
Оценки объема хранилища в действии
То, как вы используете estimate() зависит от типа данных, которые ваше приложение должно хранить. Например, вы можете обновить элемент управления в своем интерфейсе, чтобы пользователи знали, сколько места используется после завершения каждой операции хранения. В идеале вам следует предоставить интерфейс, позволяющий пользователям вручную очищать данные, которые больше не нужны. Вы можете написать код примерно так:
// 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; } } Насколько точна оценка?
Трудно не заметить тот факт, что данные, которые вы получаете от функции, — это всего лишь оценка пространства, которое использует источник. Это прямо в названии функции! Ни usage , ни значения quota не должны быть стабильными, поэтому рекомендуется принять во внимание следующее:
-
usageотражает, сколько байтов данный источник эффективно использует для данных одного и того же происхождения , на что, в свою очередь, могут влиять методы внутреннего сжатия, блоки выделения фиксированного размера, которые могут включать неиспользуемое пространство, а также наличие записей «надгробия» , которые могут быть созданы временно после удаления. Чтобы предотвратить утечку точной информации о размере, непрозрачные ресурсы перекрестного происхождения, сохраненные локально, могут добавлять дополнительные байты заполнения к общему значениюusage. -
quotaотражает объем пространства, зарезервированного в настоящее время для источника. Значение зависит от некоторых постоянных факторов, таких как общий размер хранилища, а также от ряда потенциально изменчивых факторов, включая объем неиспользуемого в настоящее время дискового пространства. Поскольку другие приложения на устройстве записывают или удаляют данные, объем места, которое браузер готов выделить для источника вашего веб-приложения, скорее всего, изменится.
Настоящее: обнаружение функций и резервные варианты
estimate() включен по умолчанию, начиная с Chrome 61. Firefox экспериментирует с navigator.storage , но по состоянию на август 2017 года он не включен по умолчанию. Вам необходимо включить настройку dom.storageManager.enabled , чтобы протестировать ее.
При работе с функциями, которые еще не поддерживаются во всех браузерах, обнаружение функций является обязательным. Вы можете комбинировать обнаружение функций с оболочкой на основе обещаний поверх старых методов navigator.webkitTemporaryStorage , чтобы обеспечить согласованный интерфейс следующего вида:
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}); }