Представляем фоновую выборку

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

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

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

Итак, что делать, если вам нужно загрузить что-то, что может занять много времени, например, фильм, подкаст или уровни игры? Для этого и предназначена функция «Фоновая загрузка» .

Функция фоновой загрузки доступна по умолчанию, начиная с Chrome 74.

Вот короткая двухминутная демонстрация, демонстрирующая традиционное положение дел по сравнению с использованием Background Fetch:

Как это работает

Фоновая выборка работает следующим образом:

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

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

На некоторых платформах (например, Android) браузер может закрыться после шага 1, поскольку браузер может передать загрузку операционной системе.

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

API

Обнаружение особенностей

Как и с любой новой функцией, вам нужно проверить, поддерживает ли её браузер. Для функции «Фоновая загрузка» всё просто:

if ('BackgroundFetchManager' in self) {
  // This browser supports Background Fetch!
}

Запуск фоновой выборки

Основной API зависит от регистрации сервис-воркера , поэтому сначала убедитесь, что вы зарегистрировали сервис-воркер. Затем:

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
    title: 'Episode 5: Interesting things.',
    icons: [{
      sizes: '300x300',
      src: '/ep-5-icon.png',
      type: 'image/png',
    }],
    downloadTotal: 60 * 1024 * 1024,
  });
});

backgroundFetch.fetch принимает три аргумента:

Параметры
id string
однозначно идентифицирует эту фоновый запрос.

backgroundFetch.fetch будет отклонен, если идентификатор совпадает с существующей фоновой выборкой.

requests Array< Request |string>
Что нужно извлечь. Строки будут обрабатываться как URL-адреса и преобразовываться в Request с помощью new Request(theString) .

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

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

options Объект, который может включать в себя следующее:
options.title string
Заголовок, который будет отображаться в браузере вместе с ходом выполнения.
options.icons Array< IconDefinition >
Массив объектов с `src`, `size` и `type`.
options.downloadTotal number
Общий размер тел ответов (после распаковки с помощью gzip).

Хотя это необязательно, настоятельно рекомендуется предоставить его. Он используется для того, чтобы сообщить пользователю объём загрузки и предоставить информацию о ходе процесса. Если вы не предоставите этот параметр, браузер сообщит пользователю, что размер неизвестен, и в результате пользователь, скорее всего, прервёт загрузку.

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

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

Предоставление множества запросов на одну фоновую загрузку позволяет объединить элементы, которые для пользователя логически представляют собой единое целое. Например, фильм может быть разбит на тысячи ресурсов (типично для MPEG-DASH ) и содержать дополнительные ресурсы, такие как изображения. Уровень игры может быть распределен по множеству ресурсов JavaScript, изображений и аудио. Но для пользователя это просто «фильм» или «уровень».

Получение существующей фоновой выборки

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

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});

…передавая идентификатор нужной фоновой выборки. get возвращает undefined если нет активной фоновой выборки с таким идентификатором.

Фоновая выборка считается «активной» с момента ее регистрации и до тех пор, пока она не завершится успешно, не завершится неудачей или не будет прервана.

Список всех активных фоновых выборок можно получить с помощью getIds :

navigator.serviceWorker.ready.then(async (swReg) => {
  const ids = await swReg.backgroundFetch.getIds();
});

Фоновые регистрации выборки

BackgroundFetchRegistration ( bgFetch в приведенных выше примерах) имеет следующее:

Характеристики
id string
Идентификатор фоновой выборки.
uploadTotal number
Количество байтов, которые необходимо отправить на сервер.
uploaded number
Количество успешно отправленных байтов.
downloadTotal number
Значение, предоставленное при регистрации фоновой выборки, или ноль.
downloaded number
Количество успешно полученных байтов.

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

result

Один из следующих вариантов:

  • "" - Фоновая загрузка активна, поэтому результата пока нет.
  • "success" — фоновая загрузка прошла успешно.
  • "failure" — фоновая загрузка не удалась. Это значение появляется только в случае полной неудачи фоновой загрузки, например, когда браузер не может повторить попытку/возобновить её.
failureReason

Один из следующих вариантов:

  • "" - Фоновая выборка не удалась.
  • "aborted" — фоновая загрузка была прервана пользователем или был вызван abort() .
  • "bad-status" — один из ответов имел статус «неудовлетворительно», например 404.
  • "fetch-error" — одна из выборок не удалась по какой-то другой причине, например, CORS, MIX, недопустимый частичный ответ или общий сбой сети, из-за которого выборку невозможно повторить.