Рекомендации по сохранению состояния приложения с помощью IndexedDB, Рекомендации по сохранению состояния приложения с помощью IndexedDB

Изучите лучшие практики синхронизации состояния приложения между IndexedDB и популярными библиотеками управления состоянием.

Когда пользователь впервые загружает веб-сайт или приложение, ему часто приходится выполнять изрядный объем работы по созданию исходного состояния приложения, которое используется для визуализации пользовательского интерфейса. Например, иногда приложению необходимо выполнить аутентификацию пользователя на стороне клиента, а затем выполнить несколько запросов API, прежде чем оно получит все данные, необходимые для отображения на странице.

Сохранение состояния приложения в IndexedDB может стать отличным способом ускорить загрузку при повторных посещениях. Затем приложение может синхронизироваться с любыми службами API в фоновом режиме и лениво обновлять пользовательский интерфейс новыми данными, используя стратегию устаревших данных при повторной проверке .

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

Сделайте свое приложение предсказуемым

Многие сложности вокруг IndexedDB связаны с тем, что существует множество факторов, которые вы (разработчик) не можете контролировать. В этом разделе рассматриваются многие проблемы, которые следует учитывать при работе с IndexedDB.

Запись в хранилище может завершиться неудачей

Ошибки при записи в IndexedDB могут возникать по разным причинам, и в некоторых случаях эти причины находятся вне вашего контроля как разработчика. Например, некоторые браузеры не позволяют осуществлять запись в IndexedDB в режиме приватного просмотра . Также существует вероятность того, что пользователь находится на устройстве, на котором почти не хватает места на диске, и браузер вообще запретит вам что-либо сохранять.

По этой причине крайне важно всегда реализовывать правильную обработку ошибок в коде IndexedDB. Это также означает, что обычно рекомендуется хранить состояние приложения в памяти (помимо его хранения), чтобы пользовательский интерфейс не прерывался при работе в режиме приватного просмотра или когда место для хранения недоступно (даже если некоторые другие функции приложения, требующие хранения, не будут работать).

Сохраненные данные могли быть изменены или удалены пользователем.

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

Хотя пользователи могут редко изменять свои локально хранящиеся данные, пользователи довольно часто их очищают. Важно, чтобы ваше приложение могло обрабатывать оба этих случая без ошибок.

Сохраненные данные могут быть устаревшими

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

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

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

Поддерживайте производительность вашего приложения

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

Как правило, операции чтения и записи в IndexedDB не должны превышать объемы, необходимые для доступа к данным.

Хотя IndexedDB позволяет хранить большие вложенные объекты как одну запись (и это, по общему признанию, весьма удобно с точки зрения разработчика), такой практики следует избегать. Причина в том, что когда IndexedDB сохраняет объект, она должна сначала создать структурированный клон этого объекта, и процесс структурированного клонирования происходит в основном потоке. Чем больше объект, тем дольше будет время блокировки.

Это создает некоторые проблемы при планировании сохранения состояния приложения в IndexedDB, поскольку большинство популярных библиотек управления состоянием (например, Redux ) работают, управляя всем вашим деревом состояний как одним объектом JavaScript.

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

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

Как и большинство передовых практик, это не правило «все или ничего». В тех случаях, когда невозможно разбить объект состояния и просто записать минимальный набор изменений, разбиение данных на поддеревья и запись только их по-прежнему предпочтительнее, чем всегда писать все дерево состояний. Небольшие улучшения лучше, чем отсутствие улучшений вообще.

Наконец, вы всегда должны измерять влияние кода, который вы пишете, на производительность . Хотя это правда, что небольшие записи в IndexedDB будут выполняться лучше, чем большие записи, это имеет значение только в том случае, если записи в IndexedDB, которые выполняет ваше приложение, действительно приводят к длительным задачам , которые блокируют основной поток и ухудшают взаимодействие с пользователем. Важно проводить измерения, чтобы понимать, для чего вы оптимизируете.

Выводы

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

Хотя правильное использование IndexedDB может значительно улучшить взаимодействие с пользователем, неправильное его использование или неспособность обрабатывать случаи ошибок могут привести к неработоспособности приложений и недовольству пользователей.

Поскольку клиентское хранилище включает в себя множество факторов, находящихся вне вашего контроля, очень важно, чтобы ваш код был хорошо протестирован и правильно обрабатывал ошибки, даже те, возникновение которых на первый взгляд может показаться маловероятным.