Оптимистичные офлайн-приложения с Vuex

TL; DR - используйте плагины Vuex вместе с localForage, чтобы легко сохранять данные приложения в оптимистической манере

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

Оптимистическая блокировка

Стратегия управления параллелизмом, которая предполагает, что конфликт обычно не возникает, поэтому сначала действует так, как если бы операция завершилась, и откатывается в случае сбоя. Эта стратегия довольно распространена в наши дни в области веб-разработки. Вы можете увидеть это в действии, когда поставите лайк на Facebook, когда напишете сообщение в блоге на Medium и практически везде. С точки зрения реализации, вы также должны помнить о том, что нужно обрабатывать сбои и как вернуться назад, когда операция не удалась. С точки зрения пользовательского опыта эта стратегия является лучшей, поскольку пользователю не нужно ждать завершения запроса.

Offline-First

Мы живем в мире без подключения к Интернету и с питанием от батарей, но наши технологии и передовой опыт - это пережиток прошлого, когда мы постоянно подключались и постоянно получали питание. - offlinefirst.org

Возможность работы в автономном режиме является обязательной и, честно говоря, не так уж и сложно, как вы увидите в этом сообщении в блоге. В основном это означает, что ваше приложение может работать даже без подключения вообще, конечно, это не означает, что будут предоставлены все функции, а только их подмножество. Для этой цели мы можем использовать Service Workers, Web SQL, IndexedDB и многие другие инструменты, предоставляемые браузером. Я использую localForage как абстракцию для автономного хранилища вместо работы с низкоуровневым API.

Vuex

Шаблон управления состоянием + библиотека для приложений Vue.js. Он служит централизованным хранилищем для всех компонентов в приложении - vuex.vuejs.org

Vuex очень похож на Redux и многие другие централизованные магазины. Я постараюсь, чтобы все в значительной степени не зависело от стека, поскольку концепции почти одинаковы в каждом централизованном магазине. Для нас самое главное - это возможность подписаться на мутации, происходящие в магазине. Таким образом мы можем кэшировать соответствующие данные или синхронизировать их с нашим сервером. Пока вы можете подписаться на мутации, подойдет любая другая библиотека.

Начнем с простого - кэширования данных для работы в автономном режиме.

Для начала нам понадобится сервис для обработки операций с кешем, назовем его Storage. Он должен экспортировать 3 функции для управления состоянием: получение, установка и удаление. Здесь все довольно просто, осталось только написать функцию для сопоставления объекта состояния с объектом кеширования. Обычно вы хотите удалить какие-то временные поля или так или иначе манипулировать состоянием.

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

Наше состояние кэшируется при каждой мутации, но мы все равно должны загружать его при запуске приложения. Давайте добавим мутацию, которая устанавливает состояние из кеша и наших плагинов (пока не обращайте внимания на плагин синхронизации, мы перейдем к нему). Мутация loadFromCache получает кэшированный объект и соответствующим образом обновляет состояние (в vuex вы должны перебирать свойства по причинам реакции). Мне также нравится держать флаг в состоянии, чтобы знать, было ли состояние уже инициализировано из кеша.

Осталось только вызывать мутацию loadFromCache при каждой загрузке приложения. Вы можете использовать его как охрану Vue Router или как хотите. Ниже представлена ​​общая концепция реализации.

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

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

Мы применили эту и многие другие техники при создании Daily Go, попробуйте!