Интервью-вопрос
Что такое IndexedDB
IndexedDB - асинхронное клиентское хранилище для структурированных данных, индексов и транзакций. В ответе важно показать, когда оно полезно, а где добавляет сложность или риск потери данных.
- Добавлен
- Редакция
Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.
Мини-квиз
Проверка перед разбором
Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.
Вопрос 1 из 60 правильно
Разбор
Разобраться, а не зазубрить
Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.
Базовая идея
IndexedDB нужен, когда приложению мало простого строкового хранилища. Это браузерная база данных для объектов. Можно создать хранилища, выбрать ключ, добавить индексы и читать данные асинхронно.
Хороший короткий ответ на интервью:
IndexedDB - это асинхронное клиентское хранилище для структурированных данных в браузере. Оно подходит для оффлайн-режима, кэша данных приложения, черновиков и больших коллекций, где нужны индексы и транзакции. Но его надо использовать осознанно. Есть миграции схемы, ошибки записей, квоты и риск, что локальные данные будут удалены.
Не ограничивайтесь фразой "это база в браузере". Добавьте, что это меняет для фронтенда. UI не должен считать запись успешной до результата операции, а критичные данные нельзя держать только локально.
Чем это отличается от простых хранилищ
localStorage и sessionStorage удобны для маленьких строковых значений. Например, для флага, темы или простой настройки. Но они синхронные и работают со строками. Если хранить там большие JSON-объекты, парсинг и запись могут блокировать главный поток, а структура быстро станет хрупкой.
IndexedDB хранит значения через structured clone. Можно сохранять обычные объекты, массивы, даты, Blob и другие поддерживаемые типы без ручного превращения всего в строку. Плюс можно делать индексы по полям, а не проходить всю коллекцию руками.
Практический вывод простой. Если данные маленькие и простые, не усложняйте. Если нужны оффлайн-данные, поиск, много записей или бинарные данные, IndexedDB выглядит хорошим кандидатом.
Как выбрать хранилище
Обычно достаточно localStorage или cookie, если это связано с HTTP.Выбирайте IndexedDB. В нем есть object stores, индексы и асинхронные операции.Смотрите в сторону Cache API. IndexedDB оставьте для метаданных и данных приложения.Нужен сервер или синхронизация. IndexedDB используйте как локальную копию, а не единственный источник истины.Как выглядит работа с базой
В IndexedDB есть важный жизненный цикл. Сначала вы открываете базу по имени и версии. Если версия выросла, браузер вызывает onupgradeneeded. Там можно создать object stores и индексы. После успешного открытия вы работаете с данными через transaction.
function openAppDb() {
return new Promise((resolve, reject) => {
const request = indexedDB.open("app-db", 1);
request.onupgradeneeded = () => {
const db = request.result;
if (!db.objectStoreNames.contains("drafts")) {
const store = db.createObjectStore("drafts", { keyPath: "id" });
store.createIndex("updatedAt", "updatedAt");
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
request.onblocked = () => reject(new Error("Database upgrade is blocked by another tab"));
});
}
async function saveDraft(draft) {
const db = await openAppDb();
const tx = db.transaction("drafts", "readwrite");
const store = tx.objectStore("drafts");
store.put({ ...draft, updatedAt: Date.now() });
return new Promise((resolve, reject) => {
tx.oncomplete = () => {
db.close();
resolve();
};
tx.onerror = () => {
db.close();
reject(tx.error);
};
tx.onabort = () => {
db.close();
reject(tx.error);
};
});
}В этом примере важен не синтаксис, а контракт. Схема создается в upgrade flow, запись идет внутри transaction, а вызывающий код получает ошибку, если данные не сохранились. Соединение закрывается после операции, чтобы не мешать будущему upgrade в другой вкладке. Без этого легко показать пользователю "черновик сохранен", хотя запись упала.
В React или Next.js не вызывайте такой код во время render и не ждите от SSR доступа к локальной базе пользователя. Запускайте чтение после маунта или по действию пользователя. Показывайте loading и проверяйте, что ответ не устарел, прежде чем обновлять state.
Главные ловушки для frontend-кода
Первая ловушка - считать IndexedDB вечным и надежным хранилищем. Браузер может ограничить место, пользователь может очистить данные сайта, а приватный режим и мобильные браузеры могут вести себя строже. Поэтому для важных сущностей нужна синхронизация с сервером или хотя бы понятный статус "сохранено локально".
Вторая ловушка - забыть, что API асинхронный и событийный. Если вы делаете optimistic UI, заранее решите, что произойдет при ошибке. Например, откатить карточку, показать retry, оставить черновик в очереди или подсветить конфликт.
Третья ловушка - обновить UI результатом старого чтения. Пользователь мог уйти на другой экран, выбрать другой документ или начать новый запрос. В компоненте нужен флаг актуальности, отмена на уровне вашего слоя данных или проверка id перед setState. Иначе IndexedDB создаст такой же race condition, как медленный сетевой запрос.
Четвертая ловушка - путать IndexedDB с Cache API. Для PWA они часто дополняют друг друга. Cache API хранит HTTP responses и хорошо работает с service worker. IndexedDB удобнее для доменных данных, метаданных, очередей отправки и поиска.
- 1Открыть базу нужной версии
- 2Создать transaction с понятным режимом
- 3Выполнить все операции над store внутри transaction
- 4Обработать success, complete, error и abort
- 5Показать UI только после подтвержденного результата или сделать rollback
- 1Считать, что add всегда сработает
- 2Обновить UI до результата без плана отката
- 3Игнорировать quota и constraint errors
- 4Менять схему без повышения версии базы
- 5Хранить важные данные без синхронизации
Что сказать про безопасность и квоты
IndexedDB не делает данные секретными. Если в приложении есть XSS, вредный скрипт может получить доступ к тем же браузерным API, что и ваш код. Поэтому хранение токена в IndexedDB не является полноценной защитой. На интервью лучше сказать спокойно. Безопасность зависит от всей модели, включая защиту от XSS, CSP, cookie strategy и серверные ограничения.
С квотами тоже не стоит называть одно точное число для всех браузеров. Правильнее сказать, что лимиты зависят от браузера, устройства, свободного места и режима хранения. Для крупных данных нужно обрабатывать ошибку записи, показывать понятный UX и иногда использовать navigator.storage.persist(), если приложению действительно нужен более устойчивый storage.
Практический вывод
В сильном ответе вы показываете не только определение, но и границы применения. IndexedDB хороша для сложных локальных данных, но требует аккуратного кода вокруг жизненного цикла базы, транзакций, ошибок и синхронизации.
Если хотите звучать практично, добавьте пример из UI. Например, вы сохранили бы в IndexedDB черновики формы или список задач для offline-режима, но после восстановления сети синхронизировали бы их с сервером и обработали конфликты. Такая формулировка показывает, что вы думаете не только про API, но и про состояние продукта.
Частые ошибки
Где обычно ошибаются
Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.
- 1
Называть IndexedDB большим localStorage
Такая формулировка звучит просто, но технически неверна. IndexedDB работает с object stores, индексами, транзакциями и structured clone, а
localStorageхранит строки и выполняет операции синхронно. - 2
Забывать про миграции схемы
Object stores и индексы нельзя надежно добавлять где угодно после открытия базы. Схему меняют в
onupgradeneededпри повышении версии. Иначе часть пользователей получит ошибку или старую структуру данных. - 3
Игнорировать ошибки транзакций
Запись может упасть из-за квоты, дубликата ключа, закрытой базы или приватного режима. Если UI уже показал успех, пользователь потеряет доверие и может потерять черновик.
- 4
Делать IndexedDB единственным источником истины
Браузерные данные может очистить пользователь, браузер или политика устройства. Для важных данных нужна синхронизация с сервером. IndexedDB лучше описывать как локальный кэш или offline-слой.
- 5
Хранить секреты без модели угроз
IndexedDB не защищает токены от XSS в вашем приложении. Если скрипт получил доступ к странице, он часто сможет читать и локальное хранилище. Безопасность решают CSP, защита от XSS, cookie strategy и серверные ограничения.
- 6
Вызывать IndexedDB во время render или SSR
indexedDBесть только в браузере. Если обратиться к нему на сервере или прямо во время render, можно получить ошибку гидратации, зависший экран или лишние чтения при каждом рендере. Безопаснее запускать чтение в effect, обработчике события или отдельном клиентском слое. Еще важно проверять, что результат относится к текущему экрану.
Follow-up
Что могут спросить дальше
Короткие ответы на вопросы, которыми проверяют понимание IndexedDB в реальном frontend-коде.
Живые ответы
Видео с похожим вопросом
Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.
Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.
Что такое Incremental DOM 😎
Incremental DOM обновляет реальный DOM по инструкциям, которые обычно генерирует компилятор шаблонов, и не держит полное виртуальное дерево в памяти. На странице разбираем, чем подход отличается от Virtual DOM и какие риски важно назвать на интервью.
Что такое preventDefault в JavaScript 😎
preventDefault отменяет стандартное действие браузера для отменяемого события, но не останавливает всплытие. Разбираем, когда его вызывать, чем он отличается от stopPropagation и какие баги он может создать во фронтенде.