Site icon 8HOST.COM

Как работают сервис-воркеры в JavaScript

Service Worker — это относительно новый API, который появился в современных веб-браузерах в течение последние нескольких лет. Это действительно важная технология – особый тип веб-воркеров, который можно установить в браузере для предоставления специальных функций, ранее недоступных для обычных веб-страниц (например, офлайн доступ к контенту).

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

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

Service Worker работает в отдельном потоке. Это означает, что вы не можете получить доступ ко многим объектам, доступным в основном потоке JavaScript, включая DOM и некоторые API, такие как XHR или файлы cookie. Положительным моментом является то, что ни одна операция сервис-воркера не может заблокировать поток пользовательского интерфейса, потому что он полностью отделен.

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

Основные характеристики сервис-воркеров

Конечная цель прогрессивных веб-приложений (PWA) — хорошо работать на мобильных устройствах. Главная проблема на мобильных устройствах — это обработка офлайн состояния.

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

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

Как установить сервис-воркер

Сервис-воркеры нужно установить в браузер, чтобы иметь возможность их использовать.

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

Лучший способ сделать это — проверить наличие serviceWorker в объекте navigator:

if (!('serviceWorker' in navigator)) {
  // service worker не поддерживается 😣
  return
}

Если сервис-воркеры поддерживаются, вы можете зарегистрировать свой сервис-воркер, указав файл, в котором его можно найти. Для сервис-воркера необходим отдельный файл, доступный браузеру. Например, вы можете поместить его в файле worker.js, расположенном в корневом каталоге.

Подождите, пока страница загрузится, затем зарегистрируете сервис-воркер с помощью метода navigator.serviceWorker.register():

window.addEventListener('load', () => {
  if (!('serviceWorker' in navigator)) {
    // service worker не поддерживается 😣
    return
  }

  navigator.serviceWorker.register('/worker.js').then(
    () => {
      // зарегистрирован
    },
    err => {
      console.error('SW registration failed! 😱', err)
    }
  )
})

Жизненный цикл сервис-воркера

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

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

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

Из чего состоит сервис-воркер

Мы только что увидели, как установить сервис-воркер, который находится в файле worker.js, но пока не изучали этот файл.

В сервис-воркере вы можете прослушивать несколько событий, генерируемых браузером:

Обслуживание кэшированных ресурсов

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

self.addEventListener('install', event => {
  event.waitUntil(
    caches
      .open('my-site-name')
      .then(cache =>
        cache.addAll([
          'favicon.ico',
          'style.css',
          'script.js',
          'https://fonts.googleapis.com/css?family=Inconsolata:400,700'
        ])
      )
  )
})

Этот фрагмент кода использует Cache API, чтобы браузер мог кэшировать все эти ресурсы под именем my-site-name.

Давайте посмотрим, как прослушивать событие fetch , чтобы предоставить пользователю кэшированный ресурс при следующем доступе к странице сайта:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      if (response) {
        //найдена запись в кэше
        return response
      }
      return fetch(event.request)
    })
  )
})

Мы проверяем, содержит ли кэш ресурс, идентифицированный свойством request. Если такого ресурса нет, запускаем fetch запрос, чтобы получить его.

Читайте также: Основы Fetch API в JavaScript

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

Обновление сервис-воркера

После того как сервис-воркер установлен, он будет продолжать работать до тех пор, пока пользователь не удалит его или пока вы не обновите его.

Чтобы обновить сервис-воркер, необходимо просто отправить его новую версию на сервер (достаточно даже изменения одного байта). Браузер сам обнаружит, что это новая версия, скачает и установит ее.

Как и при первой установке, новый сервис-воркер будет недоступен, пока пользователь не загрузит следующую страницу.