Возможность сохранять информацию локально в браузере — очень полезная функция, которая развивалась со временем. В этой статье мы рассмотрим различные типы хранилищ и способы их использования в ExtJS. В частности, мы проанализируем реализацию IndexedDB, предлагаемую библиотекой (N)ext.
Читать далее: IndexedDB и ExtJSCookie
«Классический» способ сохранения данных в браузере — использование файлов cookie, которые позволяют сохранять небольшие строки для последующего получения с сервера или непосредственно в браузере с помощью JS кода. Так же существуют настоящие базы данных: LocalStorage, SessionStorage и IndexexDB.
LocalStorage и SessionStorage
localStorage и SessionStorage — это две простые базы данных «ключ-значение», присутствующие в браузере. Существуют они в разрезе для каждого «источника» (хост+порт).
Разница между ними заключается в том, что localStorage является постоянным, а данные, содержащиеся в SessionStorage, удаляются при закрытии браузера.
Ограничения
Основные проблемы с этими типами хранения данных следующие:
- Размер данных: между различными браузерами существуют различия, но в целом невозможно сохранить более 5 МБ данных.
- Их API синхронный, поэтому, если у вас большой обьем данных или вы выполняете много операций чтения/записи, вы можете столкнуться с «подвисанием» браузера.
- Элементы сохраняются в виде строк, поэтому для более сложных объектов необходимо вручную их преобразовывать Ext.decode, Ext.encode.
Реализация в ExtJS
В ExtJS есть различные классы, которые используют эти типы хранилищ.
- Ext.util.LocalStorage. Этот класс представляет собой обертку над нативным классом localStorage браузера. Поддерживает локальное кеширование.
- Ext.state.LocalStorage. Этот класс используется для сохранения состояния\свойств компонентов (размера, положения и т. д.), (см. Ext.Stateful).
- Ext.data.proxy.LocalStorage. Этот прокси, для store, позволяет читать и записывать данные из localStorage.
- Ext.data.proxy.SessionStorage. Точно так же, как предыдущий, но читает и записывает в SessionStorage.
IndexedDB
Чтобы на не сталкиваться с ограничениями localStorage, лучше использовать IndexedDB (см. поддерживаемые браузеры). В отличие от localStorage, он позволяет веб-приложениям хранить большие объемы структурированных данных, предлагая гибкий интерфейс доступа на основе Promise.
Основне оссобенности:
- Модель данных: IndexedDB поддерживает хранение сложных объектов JavaScript, что позволяет хранить иерархически структурированные данные (вложенные обьекты и пр).
- Размер данных: IndexedDB обрабатывает большие объемы данных более эффективно, чем localStorage, и не имеет ограничений на размер самих данных.
- Интерфейс доступа: IndexedDB предоставляет более сложный интерфейс программирования, чем localStorage. Для эффективной работы с данными требуется понимание таких понятий, как транзакции, курсоры и индексы.
- Поддержка транзакций: IndexedDB поддерживает транзакции, позволяя выполнять атомарные операции над несколькими записями данных.
- Производительность: IndexedDB предназначен для эффективной обработки больших объемов данных и обеспечивает более высокую производительность, чем localStorage.
Главным недостатком IndexedDB является именно сложность API. В JS есть библиотеки, которые пытаются упростить его использование, например:
В частности, IDB-Keyval предлагает чрезвычайно упрощенный API, очень напоминающий localStorage. Это упрощение несет множество ограничений, и фактически некоторые фичи IndexedDB (например, использование транзакций) теряются. Но для тех, кто решил уйти от использования localStorage и просто нуждается в большей производительности и дисковом пространстве и синхронном API, это, безусловно, интересный выбор.
ExtJS — (N)ext
К сожалению, в ExtJS нет встроенной поддержки IndexedDB. Именно по этому родилась библиотека (N)ext, которая опубликована на GitHub. С помощью (N)ext вы можете подключиться к базе данных следующим образом:
// Если вы добавляете новое хранилище, вам необходимо увеличить версию базы данных! database = await Next.IndexedDB.open('dbname', { version: 1, stores: ['store1','store2', 'store3', 'store4'] });
Если база данных не существует, она будет создана с четырьмя хранилищами (которые не имеют ничего общего с хранилищами ExtJS, не путайте со store), которые можно рассматривать как таблицы. В связи с тем, как работает IndexedDB, важно помнить, что если требуется дополнительное хранилище, номер версии необходимо увеличить. Важно отметить, что открытие базы данных (как и практически всех других API) происходит асинхронно.
Получив ссылку на базу данных, вы можете взаимодействовать с хранилищами. Библиотека предлагает различные возможности, основные из них перечислены ниже.
Вставка/изменение элемента в хранилище
await database.store1.set(5, { name: 'Charlie' });
Как видно из примера, значение является объектом и в этом случае дополнительное преобразование не требуется.
Чтение значения
const value = await database.store1.get(5);
Также в этом случае переменная value будет обьектом.
Чтение всех ключей хранилища
const keys = await database.store1.keys();
Чтение всех значений из хранилища
const values = await database.store1.values();
Удаление значения по ключу
await database.store1.del(5);
Удаление всех элементов хранилища
await database.store1.clear();