Синхронизация данных приложения в фоновом режиме¶
Добро пожаловать на неделю 2 день 6 из серии 30 Days of PWA! В сегодняшней статье мы расскажем о фоновых сервисах современных браузеров и о том, как использовать их для различных видов синхронизации.
Фоновые сервисы¶
Современные браузеры и API сервис-воркеров привнесли в веб новые интересные возможности. Теперь некоторые части кода фронтенда можно запускать совершенно независимо от жизненного цикла основного приложения. Это означает, что вы больше не ограничены в проектировании и создании приложения как чего-то, что начинается только тогда, когда пользователь открывает соответствующий URL, и заканчивается сразу после закрытия вкладки. Теперь части вашего кода могут выполняться даже тогда, когда окна браузера с открытым в нем приложением нет, т.е. в фоновом режиме. Причем это может происходить как с уведомлением пользователя, так и без него. Решение принимаете вы, как разработчик.
В браузерах на базе Chromium существует множество API, формирующих функцию Background Services, которая позволяет выполнять код в фоновом режиме. Сегодня мы подробно рассмотрим два из них, позволяющих синхронизировать данные между приложением и браузером: Background Sync API и Periodic Background Sync API.
Однократная синхронизация при восстановлении соединения¶
Веб зависит от подключения к Интернету, что не очень хорошо для платформы приложений. Загрузив и установив приложение, вы ожидаете, что оно будет работать независимо от того, находитесь вы в сети или нет. О готовности PWA к работе в автономном режиме заботится комбинация основных событий API сервис-воркера — install
, activate
, fetch
— и Cache Storage. Но как быть с запросами, которые приложение выполняет во время работы? Как обеспечить бесперебойную работу приложения при отсутствии подключения к Интернету?
На помощь приходит API Background Sync. Он позволяет разработчикам рассматривать взаимодействие внешнего приложения с сервером как набор синхронизаций. Эти "синхронизации" будут происходить сразу после их создания ("регистрации" в терминах Background Sync API) при наличии соединения или, если соединения нет, позже, когда пользователь снова выйдет в Интернет. Отличие от всех других подходов к pre-PWA заключается в том, что "позже" может быть после того, как пользователь закрыл вкладку приложения и/или видимую часть браузера — благодаря сервису-воркеру, который всегда "дежурит" в фоновом режиме.
Обратите внимание, что данный API предоставляет только событие sync
для сервиса-воркера. Вам все равно придется сохранять данные, которые вы хотите отправить (на случай, если устройство находится в автономном режиме), и отправлять их. Если вы хотите поддерживать несколько транзакций за одну синхронизацию, то вам потребуется хранить данные и реализовать постановку их в очередь. Для хранения данных можно использовать API IndexedDB — он асинхронный, поэтому доступ к нему можно получить из сервис-воркера.
Как реализовать¶
Существует множество сценариев использования фоновой синхронизации, но наиболее простым и распространенным является следующий: воспроизведение запросов к серверу, которые не выполняются из-за того, что приложение находится в автономном режиме, после восстановления соединения. Рассмотрим, как это работает на практике для веб-клиента социальных сетей.
В основном коде приложения после того, как пользователь создал новый пост и нажал кнопку "Опубликовать", вы проверяете, не завершился ли запрос к серверу. Если да, то вы создаете синхронизацию для этой попытки. Для этого необходима активная регистрация сервис-воркера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Очень хорошей идеей будет обернуть этот код функцией обнаружения:
1 2 3 4 5 6 7 8 |
|
В сервисе-воркере вы слушаете и реагируете на событие sync
с именем sync-post
:
1 2 3 4 5 6 7 8 9 |
|
Здесь publishSavedPosts()
должна возвращать промис, указывающий на успех/неуспех отправки данных. Если он отклонен, то при следующей синхронизации будет запланирована повторная попытка.
Повторные попытки неудачных запросов могут быть автоматизированы и реализованы декларативно с помощью модуля Workbox's Background Sync.
Периодическая синхронизация¶
Большинство прикладных платформ имеют API, позволяющие приложениям периодически выполнять некоторые задачи в фоновом режиме без участия пользователя. Например, приложение для социальных сетей может время от времени получать и сохранять новые сообщения с сервера — чтобы отображать актуальную ленту при каждом запуске приложения.
А как насчет веба? Можно ли поддерживать PWA в актуальном состоянии? Да, с помощью API периодической фоновой синхронизации. С помощью этого API мы можем попросить фоновую службу браузера регулярно запускать части нашего кода, независимо от того, используется ли PWA в данный момент. Как и в случае с Background Sync, этот API только предоставляет сервису-воркеру событие, а сами задачи вы должны реализовывать самостоятельно. Например, можно получить текущую версию приложения, его содержимое и все обновленные ресурсы, добавив их в кэш браузера.
Рассмотрим, как это работает для веб-клиента социальных сетей, который может периодически обновлять содержимое своей основной ленты в фоновом режиме.
Как сделать¶
Неплохо было бы предоставить пользователю возможность самому решать, использовать эту функцию или нет. Используя интерфейс PeriodicSyncManager
зарегистрированного сервиса-воркера, можно перечислить существующие "периодические синхронизации" для установки значения (например, включения/выключения) элементов управления пользовательского интерфейса (например, переключателей, флажков), таких как "Обновлять мою ленту в фоновом режиме". Когда пользователь включает эту функцию, вы регистрируете новую периодическую синхронизацию:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Как и всегда в PWA, обнаружение особенностей является лучшей практикой:
1 2 3 4 5 6 7 8 9 10 |
|
В сервисе-воркере необходимо прослушать и отреагировать на событие periodicsync
с именем update-feed-content
:
1 2 3 4 5 6 7 8 9 |
|
Следует отметить, что в функции updateFeedContent
можно не получать новые данные. Перед отправкой запроса следует убедиться, что пользователь находится на безлимитном соединении (с помощью Network Information API) и что в хранилище браузера достаточно места (с помощью Storage Manager API).
Соображения конфиденциальности и использования ресурсов¶
API Background Sync и Periodic Background Sync предназначены для выполнения некоторого пользовательского кода (который может отправлять сетевые запросы) в фоновом режиме в любое время без уведомления пользователя. Это вызывает как минимум две проблемы: конфиденциальность и использование ресурсов. Любой сетевой запрос — это потенциальная возможность утечки истории и отслеживания местоположения. А выполнение любого кода потребляет ресурсы процессора, памяти, аккумулятора и, при необходимости, сетевые ресурсы. Чтобы избежать этих проблем, обе спецификации требуют:
-
Наличие разрешения Background Sync для источника. По умолчанию оно имеет состояние
allow
, но пользователи могут его запретить. -
Ограничение количества повторных попыток фоновой синхронизации и длительности периодической синхронизации. Это не определено в спецификации API, но для периодической синхронизации браузеры используют индекс Site Engagement (количество и продолжительность взаимодействий с пользователем) для конкретного источника — и конкретного устройства — для расчета точных интервалов. В лучшем случае это несколько часов. Если вам интересно, вы можете самостоятельно проверить индекс вовлеченности сайта, зайдя на сайт about://site-engagement/ в браузере на базе Chromium.
- Время выполнения кода ограничено временем жизни сервис-воркера, которое составляет несколько секунд. Поэтому злоупотреблять аппаратными средствами устройства за счет тяжелых вычислений или перерасхода сетевых ресурсов достаточно сложно.
- События
sync
иperiodicsync
выполняются только в режиме онлайн.
К API периодической фоновой синхронизации предъявляется несколько дополнительных требований:
periodicsync
будет происходить только в известной сети (той, к которой пользователь был подключен ранее).- Он работает только для установленных веб-приложений.
Тестирование и отладка¶
Проверить, как работают реализованные вами фоновые сервисы, может оказаться нелегкой задачей: вы как разработчик не можете полностью контролировать точное время прихода событий синхронизации на сервис-воркер. К счастью, у нас есть набор помощников в DevTools браузера на базе Chromium.
Перейдите в панель Application → Service Workers, чтобы отправить события sync
и periodicsync
на сервис-воркер вручную:
В разделе Background Services вкладки Application можно щелкнуть на отлаживаемом API, чтобы увидеть события (как "реальные", так и "ручные"), которые были отправлены сервису-воркеру. Чтобы "поймать" и отладить реальные (распределенные по часам и дням, если речь идет о периодических синхронизациях), можно воспользоваться пиктограммой "Запись" и вести журнал событий на срок до трех дней.
Подробнее о фоновой синхронизации¶
- Синхронизация и обновление PWA в фоновом режиме статья на Microsoft Docs
- Спецификации для Background Sync API и Periodic Background Sync API
- Документация по API для Background Sync API и Periodic Background Sync API на сайте Mozilla Developer Network.