Библиотека idb-keyval предоставляет простой и удобный API для работы с IndexedDB, позволяя хранить пары ключ–значение в браузере. Одной из ключевых особенностей является возможность совместного использования данных между несколькими вкладками одного сайта. Понимание этого механизма критически важно для реализации реактивных приложений и синхронизации состояния интерфейса в реальном времени.
IndexedDB изначально предназначен для локального хранения данных и
обеспечивает независимый доступ из разных вкладок.
Любые изменения, внесённые в базу через idb-keyval,
становятся доступными другим вкладкам почти мгновенно. Библиотека
не добавляет дополнительной прослойки синхронизации,
поэтому синхронизация достигается через нативные браузерные события
storage и транзакции IndexedDB.
Особенности поведения:
get, set, del и
clear возвращают Promise. Это позволяет
корректно работать с несколькими вкладками, не блокируя интерфейс.set, другие вкладки получают доступ к новым данным только
после завершения транзакции.Базовый набор методов остаётся стандартным:
import { get, set, del, clear, keys, upd ate } from 'idb-keyval';
Сохранение данных:
await se t('userSettings', { theme: 'dark', fontSize: 16 });
Получение данных из другой вкладки:
const settings = await get('userSettings');
console.log(settings); // { theme: 'dark', fontSize: 16 }
Обновление данных с учётом текущего состояния:
await upd ate('userSettings', old => ({ ...old, fontSize: 18 }));
Удаление и очистка:
await del('userSettings');
await clear();
Для реактивного обновления интерфейса при изменении данных в других
вкладках используют BroadcastChannel или
событие storage для простых случаев:
const channel = new BroadcastChannel('idb-keyval-sync');
channel.onmess age = (event) => {
console.log('Данные изменены в другой вкладке:', event.data);
};
// Отправка события после изменения данных
await se t('userSettings', { theme: 'light' });
channel.postMessage({ key: 'userSettings', value: { theme: 'light' } });
Особенности:
localStorage + событие storage:localStorage.setItem('userSettings', JSON.stringify({ theme: 'light' }));
window.addEventListener('storage', (event) => {
if (event.key === 'userSettings') {
console.log('Обновлено значение:', JSON.parse(event.newValue));
}
});
Использовать отдельный канал для синхронизации
Для разных категорий данных рекомендуется создавать отдельные
BroadcastChannel, чтобы избежать лишнего трафика
сообщений.
Обновление состояния интерфейса Любые изменения, приходящие из других вкладок, должны аккуратно обрабатываться. Необходимо проверять текущий статус компонента перед применением изменений, чтобы избежать конфликтов.
Минимизировать количество операций записи Частые
вызовы set создают нагрузку на IndexedDB и могут вызывать
задержки при синхронизации. Для больших объектов лучше использовать
батчи или update.
Конфликт версий данных Если несколько вкладок
одновременно изменяют один и тот же ключ, лучше использовать
update с функцией редуцирования состояния, чтобы
агрегировать изменения, а не перезаписывать их.
Использование idb-keyval для совместного доступа к
хранилищу между вкладками обеспечивает простоту API и
возможность реактивного управления состоянием.
Комбинация IndexedDB и BroadcastChannel создаёт надёжный
механизм синхронизации, а правильная архитектура приложения позволяет
избежать конфликтов и задержек при обновлениях данных.