Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Общие лимиты IndexedDB и их природа
IndexedDB — это низкоуровневое API для хранения больших объемов структурированных данных в браузере. В отличие от Web Storage (локальное хранилище), IndexedDB не имеет жесткого, единого лимита вроде «5 МБ» или «10 МБ». Его ограничения определяются комбинацией факторов: свободным местом на диске, глобальными квотами хранилища браузера, политикой «группы происхождения» (origin) и реализацией в конкретном браузере.
Ключевые принципы квотирования
1. Квота на источник (Origin Storage Quota)
Браузеры выделяют каждому источнику (протокол + домен + порт) общий лимит для всех типов постоянного хранилища: IndexedDB, Cache API, локальное хранилище файловой системы (File System Access API). Эта квота обычно динамическая.
- Chrome/Edge: примерно 80% свободного места на диске делится между всеми посещенными сайтами. На практике это может составлять гигабайты на современных устройствах, если диск почти пуст.
- Firefox: использует гибридную модель — минимум 2 ГБ на источник, но может быть больше в зависимости от свободного места.
- Safari: традиционно более консервативен — примерно 1 ГБ на источник (но может меняться в новых версиях).
2. Принцип «просить нельзя, брать» (Quota Management API)
Чтобы записать данные сверх небольшого начального лимита (обычно несколько десятков МБ), сайт должен явно запросить увеличение квоты через navigator.storage.estimate() и navigator.storage.persist(). Пользователь при этом не видит стандартного диалога подтверждения — браузер принимает решение на основе эвристик (частота посещений, важность сайта).
// Пример проверки и запроса квоты
async function checkAndRequestQuota() {
// Получаем текущее использование и квоту
const estimation = await navigator.storage.estimate();
console.log(`Используется: ${estimation.usage} байт`);
console.log(`Квота: ${estimation.quota} байт`);
// Просим браузер сохранить данные персистентно
const isPersisted = await navigator.storage.persist();
console.log(`Данные сохранятся после очистки? ${isPersisted}`);
}
checkAndRequestQuota();
3. Лимиты на уровне базы данных и объекта
- Размер одной записи: теоретически ограничен размером квоты, но на практике лучше не хранить объекты > 100-200 МБ из-за производительности и ограничений сериализации.
- Количество баз данных: обычно несколько десятков на источник.
- Количество хранилищ объектов (Object Stores): сотни на базу данных.
Практические ограничения и обходные пути
Стратегии работы с большими объемами
-
Разбивка данных: вместо одного огромного объекта храните связанные данные в отдельных записях.
// Плохо: один огромный объект // await store.put({ id: 1, hugeData: ... }); // Лучше: разбить на части await store.put({ id: 1, part: 0, data: chunk1 }); await store.put({ id: 1, part: 1, data: chunk2 }); -
Компрессия данных: сжатие массивов, строк перед сохранением.
// Пример с простой компрессией JSON const data = { /* большой объект */ }; const compressedString = LZString.compress(JSON.stringify(data)); await store.put({ id: 1, compressed: compressedString }); -
Инкрементальное хранение: сохранять только дельты изменений.
Ограничения по производительности
- Транзакции имеют timeout (по умолчанию 60 секунд в некоторых браузерах).
- Синхронные операции отсутствуют — все асинхронное.
- Параллельные транзакции на одном хранилище могут блокировать друг друга.
Пример обработки переполнения
async function safePut(store, data) {
try {
await store.put(data);
} catch (error) {
if (error.name === 'QuotaExceededError') {
// 1. Пробуем очистить устаревшие данные
await clearOldData(store);
// 2. Пробуем снова
try {
await store.put(data);
} catch (retryError) {
// 3. Запрашиваем больше места
const granted = await requestMoreQuota();
if (granted) {
await store.put(data);
} else {
throw new Error('Недостаточно места даже после запроса');
}
}
} else {
throw error;
}
}
}
Важные нюансы
- Режим инкогнито: квоты обычно значительно меньше (50-100 МБ), данные удаляются после закрытия окна.
- Мобильные браузеры: могут иметь более агрессивные политики очистки при нехватке места.
- Прогрессивные веб-приложения (PWA): могут получить повышенные лимиты через
beforeinstallpromptи явный запрос персистентности.
Рекомендации для разработчиков
- Всегда обрабатывайте
QuotaExceededError. - Используйте
navigator.storage.estimate()для мониторинга. - Реализуйте graceful degradation при нехватке места.
- Для критичных данных используйте
navigator.storage.persist(). - Тестируйте на реальных устройствах с разным заполнением диска.
В итоге, практический лимит IndexedDB составляет от 1 до 10+ ГБ для обычных сайтов при наличии свободного места на диске, но успешная работа с объемами > 100 МБ требует тщательного проектирования архитектуры хранения и обработки ошибок.