Представляем фоновую синхронизацию

Джейк Арчибальд
Jake Archibald

Опубликовано: 8 декабря 2015 г.

Фоновая синхронизация — это веб-API, позволяющий откладывать действия до тех пор, пока у пользователя не установится стабильное соединение. Это помогает пользователям отправлять любые файлы, которые они хотят, как только это станет возможно.

Browser Support

  • Chrome: 89.
  • Край: 89.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

Source

Проблема

Интернет — отличное место, чтобы тратить время впустую. Не тратя время в интернете, мы бы не знали, что кошки не любят цветы , хамелеоны обожают мыльные пузыри , или что Эрик Бидельмангерой мини-гольфа конца 90-х .

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

  1. Телефон вынут из кармана.
  2. Достичь небольшой цели.
  3. Телефон снова в кармане.
  4. Вернитесь к жизни.

К сожалению, этот опыт часто прерывается плохим соединением. Все мы через это проходили. Вы смотрите на белый экран или вращающийся индикатор загрузки, и понимаете, что лучше бы просто сдаться и продолжить жить своей жизнью, но всё же ждёте ещё 10 секунд на всякий случай. А после этих 10 секунд? Ничего.

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

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

В данный момент, если пользователь нажимает кнопку «Отправить» в сообщении, ему приходится смотреть на индикатор загрузки, пока он не завершит загрузку. Если он пытается перейти на другую страницу или закрыть вкладку, мы используем onbeforeunload , чтобы отобразить сообщение типа: «Нет, вам нужно еще немного посмотреть на этот индикатор. Извините». Если у пользователя нет подключения к интернету, мы сообщаем ему: «Извините, вам нужно вернуться позже и попробовать снова».

Фоновая синхронизация позволяет добиться лучших результатов.

Решение

В следующем видео представлена ​​демонстрация Emojoy — чата, использующего только эмодзи. Это прогрессивное веб-приложение , работающее в автономном режиме. Приложение использует push-уведомления и синхронизацию в фоновом режиме.

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

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

Фоновая синхронизация доступна начиная с Chrome 49.

Как запросить фоновую синхронизацию

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

Подобно push-уведомлениям, он использует сервис-воркер в качестве целевого объекта события, что позволяет ему работать, даже когда страница не открыта. Для начала зарегистрируйтесь для синхронизации со страницы:

// Register your service worker:
navigator.serviceWorker.register('/sw.js');

// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});
 ```

Then listen for the event in `/sw.js`:

```js
self.addEventListener('sync', function(event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

Вот и всё! doSomeStuff() должна возвращать промис, указывающий на успех или неудачу выполняемой операции. Если он выполняется, синхронизация завершена. Если нет, планируется повторная синхронизация. Повторные попытки синхронизации также ожидают подключения и используют экспоненциальную задержку.

Имя тега синхронизации (в примере — 'myFirstSync') должно быть уникальным для каждой синхронизации. Если вы регистрируете синхронизацию, используя тот же тег, что и ожидающая синхронизация, она объединяется с существующей синхронизацией. Это означает, что вы можете регистрировать синхронизацию "очистка исходящих сообщений" каждый раз, когда пользователь отправляет сообщение, но если он отправит 5 сообщений в автономном режиме, вы получите только одну синхронизацию, когда он подключится к сети. Чтобы получить 5 отдельных событий синхронизации, используйте уникальные теги.

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

Применение фоновой синхронизации

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

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

Демоверсия Википедии в автономном режиме

Это офлайн-демонстрация Википедии, которую я создал для Supercharging Page Load . С тех пор я добавил в неё некоторые функции фоновой синхронизации.

Попробуйте сами:

  1. Оставьте браузер открытым в этой вкладке.
  2. Отключитесь от сети, включив режим полета или выключив Wi-Fi.
  3. Перейдите по ссылке, чтобы прочитать другую статью.
  4. Вам должно появиться сообщение о том, что страница не загрузилась (это сообщение также появится, если страница просто долго загружается).
  5. Согласиться на получение уведомлений.
  6. Закройте браузер.
  7. Зайдите в интернет
  8. Вы получите уведомление, когда статья будет загружена, сохранена в кэше и готова к просмотру!

Используя этот шаблон, пользователь может положить телефон в карман и заниматься своими делами, зная, что телефон оповестит его, когда достанет то, что ему нужно.

Разрешения

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

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

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

Разумеется, эти ограничения могут быть ослаблены или ужесточены в зависимости от реального использования.

Прогрессивное улучшение

Пока мы ждём, когда фоновая синхронизация станет стандартной функцией, вы можете использовать её в качестве поэтапного улучшения:

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navigator.serviceWorker.ready.then(function(reg) {
    return reg.sync.register('tag-name');
  }).catch(function() {
    // system was unable to register for a sync,
    // this could be an OS-level restriction
    postDataFromThePage();
  });
} else {
  // serviceworker/sync not supported
  postDataFromThePage();
}

Если сервис-воркеры или фоновая синхронизация недоступны, просто публикуйте контент со страницы так же, как вы делали бы это сегодня.

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

Будущее

Мы планируем добавить фоновую синхронизацию в стабильную версию Chrome в первой половине 2016 года, параллельно работая над её вариантом — «периодической фоновой синхронизацией». При периодической фоновой синхронизации можно будет запрашивать событие с ограничением по временному интервалу, состоянию батареи и состоянию сети. Конечно, для этого потребуется разрешение пользователя, и браузер сам будет определять, когда и как часто будут происходить эти события. Другими словами, новостной сайт может запрашивать синхронизацию каждый час, но браузер может знать, что вы читаете этот сайт только в 7:00, поэтому синхронизация будет запускаться ежедневно в 6:50. Эта идея немного отодвинута на второй план по сравнению с разовой синхронизацией, но она уже в разработке.

Постепенно мы переносим успешные решения из Android и iOS в веб-среду, сохраняя при этом все, что делает веб-технологии такими замечательными!