Сервис-воркеры позволяют разработчикам эффективнее управлять кэшированием ресурсов, чтобы пользователи могли продолжать использовать приложение даже при разрыве интернет-соединения. В этой статье разберем, как сервис-воркер может вывести производительность на новый уровень.
Что такое сервис-воркеры
Service worker — это особый тип JavaScript воркера, который представляет собой сценарий, выполняемый в фоновом режиме браузера пользователя. Он похож на прокси-сервер, размещенный между вашим приложением, браузером и сетью. Помимо прочего, сервис-воркеры позволяют приложениям продолжать работу в автономном режиме в случае потери подключения к интернету.
Эти сценарии предоставляют разработчикам больший контроль над обработкой запросов приложений и позволяют избежать негативного пользовательского опыта, если запрос зависнет.
Как сервис-воркеры улучшают производительность
У всех такое было: вы просматриваете веб-сайт, нажимаете на ссылку и встречаетесь с какой-либо вариацией сообщения «Не удается подключиться к интернету». Вы нажимаете кнопку назад и видите то же самое. Пока соединение не будет восстановлено, вы можете только играть в dino runner, если используете Chrome. Сервис-воркеры позволяют избежать этого нежелательного сценария.
Одно из самых больших преимуществ сервис-воркеров — способность поддерживать работу в оффлайн-режиме. В прошлом для обеспечения ограниченной автономной поддержки можно было использовать API AppCache, но теперь есть сервис-воркеры, и они гораздо лучше.
Загрузка данных из локального кэша всегда занимает меньше времени, чем запрос к серверу. Если вы кэшируете все ресурсы вашего приложения, то можете значительно улучшить время загрузки для посетителей, возвратившихся на сайт. Возрастает вероятность того, что они будут возвращаться снова и снова.
Как работают сервис-воркеры?
Сценарии сервис-воркеров независимы от вашего сайта или приложения. У них свой собственный жизненный цикл:

После того, как воркер будет зарегистрирован из JavaScript, браузер установит его. Если он правильно сконфигурирован, то начнет кэшировать статические ресурсы страницы немедленно, в ином случае вам придется повторить установку.
Если установка прошла успешно, сценарий активируется и получает контроль над всеми страницами в своей области видимости. Чтобы воркер заработал, установившая его страница должна перезагрузиться. После этого он может переключаться между двумя состояниями: обработка событий fetch
и message
или прекращение работы для экономии памяти.
Необходимые условия
Сервис-воркеры — замечательная технология по многим причинам, но они теоретически могут предоставить хакерам возможности для проникновения в ваше веб-приложение. Для защиты от атак типа «человек посередине» сценарии могут быть зарегистрированы только на страницах, обслуживаемых по протоколу HTTPS. Во время разработки можно использовать воркеры через localhost, но для работающего приложения необходимо настроить защищенный протокол.
Стоит также отметить, что большинство основных веб-браузеров (кроме IE) уже поддерживают сервис-воркеры.

Как зарегистрировать сервис-воркер
Сервис-воркеры основаны на JavaScript обещаниях (promises), поэтому прежде чем начать работу, будет полезно в них разобраться.
Прежде всего, необходимо зарегистрировать воркер на вашей странице. Это можно сделать из JavaScript-файла верхнего уровня, например, из app.js
. Так вы сообщите браузеру, где находится файл нужного скрипта.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('https://your-site/sw.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
Сначала этот код проверяет, поддерживает ли браузер технологию воркеров, и лишь после этого регистрирует файл sw.js
. Перезагрузите страницу, чтобы закончить установку. Если вы используете инструменты разработчика Chrome, загляните в раздел service workers во вкладке Application.
Как установить сервис-воркер
Прежде чем ваш воркер сможет что-то сделать, вы должны установить обработчик события install
и указать, какие файлы следует кэшировать. Откройте файл sw.js
и добавьте следующий код:
var cacheName = 'site-cache-v1';
var assetsToCache = ['asset.js'];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(assetsToCache);
})
);
});
Вы можете добавить любые другие файлы в массив assetsToCache
.
Как получать события
После успешной установки, воркер активируется. Следующий шаг — возврат кэшированных ответов. Для этого можно использовать следующий кусок кода:
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
Здесь определяется событие fetch и создается обещание caches.match. При запросе метод пытается найти любой закэшированный воркером ресурс. Если не получится, то будет сделан обычный запрос к серверу.
Поддержание актуальности
В этой статье разобрано только начало работы работы с сервис-воркерами. Для длительной автономной работы сервис-воркеров необходимо периодически обновлять. Узнать больше об этом можно здесь.
Советы по кэшированию
Способ реализации Service workers зависит от архитектуры веб-приложения. Вот несколько советов, которые помогут вам:
Потоковые ответы
Если большинство ваших страниц содержат статическую шапку и подвал, лучше всего обрабатывать навигационные запросы с помощью потокового ответа, состоящего из отдельно кэшированных подресурсов. Потоки позволяют приложению отвечать на запросы навигации кэшированными фрагментами HTML.
В некоторых ситуациях, например, когда HTML-код зависит от данных из CMS, связь с сетью неизбежна. Тем не менее, внедрение сервис-воркеров и потоковых ответов улучшает пользовательский опыт, так как часть страницы будет отображена сразу, пока остальной код еще не загрузился.
Кэширование статического HTML-кода
Если веб-приложение состоит из статических HTML-документов, можно вовсе обойтись без связи с сетью.
Вам просто нужно создать service worker, который возвращает кэшированный HTML. Конечно, необходима некоторая неблокирующая логика для поддержания HTML в актуальном состоянии при внесении изменений. Для этого используется политика stale-while-revalidate:
self.addEventListener('fetch', event = {
if (event.request.mode === 'navigate') {
event.respondWith(async function() {
const normalizedUrl = new URL(event.request.url);
normalizedUrl.search = '';
const fetchResponseP = fetch(normalizedUrl);
const fetchResponseCloneP = fetchResponseP.then(r => r.clone());
event.waitUntil(async function() {
const cache = await caches.open('my-cache-name');
await cache.put(normalizedUrl, await fetchResponseCloneP);
}());
return (await caches.match(normalizedUrl)) || fetchResponseP;
}());
}
});
Как вариант, вы можете использовать Workbox для создания воркера, способного кэшировать ваши статические ресурсы, обслуживать их и поддерживать в актуальном состоянии.
Одностраничные приложения
Интеграция сервис-воркера в архитектуру App Shell позволяет одностраничным приложениям с одной страницей не обращаться к сети при обработке навигационных запросов. После установки и активации обработчиков добавьте этот код для кэширования и обновления app-shell.html:
self.addEventListener('fetch', event => {
if (event.request.mode === 'navigate') {
event.respondWith(caches.match('app-shell.html'));
}
});
Теперь все навигационные запросы должны возвращать кэшированную копию HTML-документа, содержащего основные элементы приложения. Приведенный выше код также включает логику маршрутизации на стороне клиента для отображения содержимого на основе URL-адреса.
Измерение увеличения производительности
Конечно, точная количественная оценка производительности должна основываться на реальных данных. Инженер Google опубликовал тематическое исследование о том, как создатели веб-приложения Google I/O измеряли влияние сервис-воркеров на производительность с помощью Google Analytics.
Разработчики начали с перечисления вопросов, на которые должны были ответить собранные данные. Во-первых, они хотели знать, является ли кэширование с помощью воркеров более эффективным, чем дефолтное HTTP-кэширование. При повторном посещении пользователи ожидают, что страницы будут загружаться быстрее, поэтому важно знать, действительно ли воркеры ускоряют работу приложения.
Затем нужно было решить, какие показатели лучше всего характеризуют скорость. «Время загрузки страницы» не отражает момент, после которого со страницей можно взаимодействовать. Гораздо полезнее такие метрики как первая значимая отрисовка и первое взаимодействие, они отражают восприятие пользователей. После определения правильных вопросов и нужных показателей можно оценить необходимость и возможность оптимизации.
Резюме
Сервис-воркеры не только повышают производительность сети. Например, они могут использоваться для реализации push-уведомлений, что особенно полезно в мобильных приложения. В будущем сервис-воркеры смогут делать еще много полезных вещей, например, осуществлять геозонирование. Другими словами, пора начинать экспериментировать с воркерами, потому что в ближайшее время они точно не исчезнут.
0 комментариев