Как стать автором
Обновить

Визуализация работы сервис-воркеров

Время на прочтение 5 мин
Количество просмотров 15K
Автор оригинала: Roberto Hernandez


Доброго времени суток, друзья!

Вероятно, многие из вас слышали о таком новшестве в экосистеме JavaScript, как сервис-воркеры (Service Workers), которые являются ключевым элементом современной веб-разработки. Сервис-воркеры становятся все более востребованными, в первую очередь, благодаря популярности прогрессивных веб-приложений (Progressive Web Applications — PWA).

Когда я впервые услышал о них, я задался вопросом: «Когда мы должны использовать сервис-воркеры? В каким сценариях или контексте мы можем их использовать?»

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

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

Что есть сервис-воркер?


Серсис воркер — это скрипт, запускаемый браузером в фоновом процессе. Помните, что сервис-воркер совершенно не зависит от страницы, с которой он взаимодействует или которой он служит (to serve — служить).

По сути, сервис-воркер представляет собой прокси сервер между веб-приложением, браузером и сетью.

Сервис-воркеры позволяют веб-приложениям работать подобно нативным приложениям.

Несколько фактов о сервис-воркерах


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

Как сервис-воркеры работают? Беглый взгляд


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

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



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


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

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



Самые распространенные случаи использования


Теперь, когда мы знаем, как работают сервис-воркеры, настало время поговорить о том, где они используются.

Кеширование


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

  • Только кеширование — у вас есть статический контент, который никогда не меняется.
  • Сеть или кеш — вы хотите показывать пользователям актуальный контент с условием быстрой загрузки.
  • Кеш и обновление — вы хотите отображать контент мгновенно и не возражаете против периодической синхронизации с сервером.
  • Кеш, обновление и перезагрузка — вы хотите показывать контент максимально быстро, подспудно обновляя отдельные его части и отображая их каким-либо «бесшовным» способом.

Веб-пуш (Web Push)


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

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

Более сложные примеры использования


API аналитики


У меня есть приложение. И я хочу добавить в него возможность следить за использованием приложения. Для этого я беру синхронное API для обновления собранных данных время от времени.

Балансировщик загрузки


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

Я настоятельно рекомендую вам посетить ServiceWorke.rs для более подробного изучения сервис-воркеров.

Отрабатываем навыки


Как я всегда говорю: «Хочешь научиться плавать — лезь в воду». Изучение теории — вещь замечательная, но пока не испачкаешь руки, ничему не научишься.

Регистрация сервис-воркера


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

// проверяем поддержку браузером
if('serviceWorker' in navigator){
    console.log('Сервис-воркер поддерживается')
    // осуществляем регистрацию после загрузки страницы
    // для этого добавляем обработчик события "load"
    window.addEventListener('load', () => {
        // регистрируем сервис-воркер
        navigator.serviceWorker
        .register('/service-worker.js')
        .then(registration => {
            // регистрация прошла успешно
            console.log(`Сервис-воркер успешно зарегистрирован, scope: ${registration.scope}`) // scope - подмножество контента, которое находится под контролем сервис-воркера
        })
    })
    .catch(error => {
        // регистрация провалилась
        console.log(`В процессе регистрация возникла ошибка: ${error}`)
    })
}

В работе сервис-воркера можно убедиться, перейдя по адресу: Chrome://inspect/#service-workers.



Также информацию о состоянии сервис воркера можно получить в инструментах разработчика: Application -> Service Workers.



Что дальше?


Теперь нам нужно закешировать все файлы. Мы можем выбирать файлы для кеширования. Вот как это выглядит:

// название кеша
const CACHE_NAME = 'example.com-v1'
// выбираем файлы для кеширования
const cacheAssets = ['index.html', 'about.html', 'js/main.js']
// добавляем обработчик события "install"
self.addEventListener('install', e => {
    console.log('Сервис-воркер установлен')
    e.waitUntil(
        caches
            .open(CACHE_NAME)
            .then(cache => {
                console.log('Сообщение от сервис-воркера: файлы кешируются')
                cache.addAll(cacheAssets)
            })
            .then(() => {
                self.skipWaiting()
            })
    )
})

Вот что здесь происходит:

  1. Определяем название кеша (example.com-v1).
  2. Выбираем файлы для кеширования. Для этого создаем массив.
  3. Внутри обработчика события «install» велим браузеру ожидать завершения промиса, затем открываем кеш, который будет сохранен под именем «example.com-v1».
  4. Наконец, добавляем выбранные файлы в кеш.

Удаляем неиспользуемый кеш


Далее нам необходимо удалить старые версии кеша:

// добавляем обработчик события "activate"
self.addEventListener('activate', e => {
    console.log('Сервис-воркер активирован')
    e.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(cache => {
                    if(cache !== CACHE_NAME){
                        console.log('Производится удаление старого кеша')
                        return caches.delete(cache)
                    }
                })
            )
        })
    )
})

Получение ответа


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

Его можно получить с помощью обработчика события «fetch»:

// добавляем обработчик события "fetch"
self.addEventListener('fetch', e => {
    e.respondWith(
        fetch(e.request)
            .then(res => {
                const copyCache = res.clone()
                caches.open(CACHE_NAME).then(cache => {
                    cache.put(e.request, copyCache)
                })
                return res
            })
            .catch(error => caches.match(e.request).then(res => res))
    )
})

Весь код можно посмотреть здесь.

Благодарю за внимание.
Теги:
Хабы:
+17
Комментарии 3
Комментарии Комментарии 3

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн