Storage API: проверка доступного пространства

Idb-keyval — это легковесная обёртка для IndexedDB в браузере, обеспечивающая удобное хранение данных в виде ключ–значение. Она скрывает сложность низкоуровневого API IndexedDB, позволяя использовать простые методы get, set, delete и clear.

Однако при работе с хранилищем важно учитывать доступное пространство браузера, поскольку IndexedDB не гарантирует бесконечное хранение, а лимиты зависят от браузера, устройства и контекста (например, локально или в приватном режиме).


Проверка доступного пространства с помощью Storage API

Современные браузеры поддерживают navigator.storage.estimate(), который возвращает объект с информацией о доступной памяти:

import { set, get } from 'idb-keyval';

async function checkStorage() {
    if (navigator.storage && navigator.storage.estimate) {
        const { usage, quota } = await navigator.storage.estimate();
        console.log(`Используется: ${usage} байт`);
        console.log(`Доступно: ${quota} байт`);
    } else {
        console.log('API оценки хранилища недоступно');
    }
}
  • usage — количество байт, уже занятое всеми хранилищами сайта (IndexedDB, localStorage и др.).
  • quota — максимально доступный размер хранилища для текущего домена.

Эти данные позволяют динамически контролировать размер хранимых данных и избегать ошибок переполнения.


Объединение Idb-keyval с проверкой доступного пространства

Idb-keyval не предоставляет встроенной функции для проверки лимитов, но её можно реализовать через Storage API. Например, перед сохранением большого объекта:

async function safeSet(key, value) {
    const stringValue = JSON.stringify(value);
    const size = new Blob([stringValue]).size;

    const { usage, quota } = await navigator.storage.estimate();
    const available = quota - usage;

    if (size > available) {
        throw new Error('Недостаточно места для сохранения данных');
    }

    await set(key, value);
}
  • Вычисление размера объекта через Blob позволяет получить точное количество байт.
  • Сравнение с доступной памятью предотвращает ошибки QuotaExceededError.

Работа с большими объёмами данных

При сохранении больших структур данных рекомендуется:

  1. Разбивать объекты на части Вместо хранения гигантских массивов или объектов, разделять их на отдельные ключи:
await set('userProfiles_chunk1', chunk1);
await set('userProfiles_chunk2', chunk2);
  1. Использовать сжатие данных JSON-объекты можно сжимать через библиотеки типа lz-string, уменьшая занимаемое пространство:
import LZString from 'lz-string';

const compressed = LZString.compress(JSON.stringify(largeObject));
await set('compressedData', compressed);
  1. Периодическая очистка устаревших данных Регулярно удалять старые записи через delete или clear для освобождения места.

Мониторинг использования пространства

Для долгоживущих приложений полезно отслеживать использование хранилища в реальном времени. Пример функции для логирования:

async function logStorageUsage() {
    const { usage, quota } = await navigator.storage.estimate();
    console.log(`Используемая память: ${(usage / 1024 / 1024).toFixed(2)} МБ`);
    console.log(`Доступная память: ${(quota / 1024 / 1024).toFixed(2)} МБ`);
}

Можно вызвать её перед каждым крупным сохранением или по расписанию, чтобы избежать неожиданного переполнения.


Особенности браузеров

  • Chrome и Edge: лимит примерно 6% от свободного пространства на диске для каждого происхождения.
  • Firefox: лимит около 50% свободного пространства на диске, но с предупреждениями при больших объёмах.
  • Safari: лимит гораздо более строгий, особенно в приватном режиме — часто не более нескольких МБ.

Следует учитывать эти различия при планировании хранения больших объёмов данных.


Резюме ключевых моментов

  • Idb-keyval упрощает работу с IndexedDB, но не управляет лимитами хранения.
  • Storage API (navigator.storage.estimate) позволяет оценить доступное пространство и избежать ошибок переполнения.
  • Большие объекты стоит разбивать, сжимать и периодически очищать.
  • Учитывать особенности разных браузеров и режимов работы.

Эти практики позволяют безопасно и эффективно использовать Idb-keyval для хранения данных в браузере, обеспечивая стабильную работу приложений даже при ограниченных ресурсах.