Как заставить блог Jekyll работать в автономном режиме с помощью Service Workers
Опубликовано: 2017-01-26Short Bytes: Знаете ли вы, что с появлением Service Workers можно заставить веб-сайты работать в автономном режиме! Такие веб-приложения называются PWA (Progressive Web Apps). В этом практическом руководстве я собираюсь помочь вам использовать сервисного работника, чтобы заставить блог/веб-сайт на основе Jekyll работать в автономном режиме, а также некоторые интересные вещи, которые с ним связаны.
(ПРИМЕЧАНИЕ . Фрагменты кода в статье взяты из репозитория кода моего блога. При необходимости на него можно ссылаться. Если вы новичок в Jekyll, вы можете прочитать 3-ю серию статей о хитростях CSS.)
ЗАДНИЙ ПЛАН
Ранее существовал кеш приложений на основе файла YAML, который был очень жестко закодирован по своей природе и не мог использоваться для динамического кэширования ресурсов и веб-страниц. Входите, сервисные работники. Простой Javascript API на основе простых событий для динамического кэширования сервис-воркеров для хранения ресурсов, чтобы их можно было использовать для обслуживания веб-страниц при отсутствии сети.
Сервисные работники появились в Chrome Canary в 2014 году, но его спецификация все еще пересматривается/дополняется и разрабатывается. В 2015 и 2016 годах команда Google Chrome активно распространяла информацию об этой новой технологии в браузерах. Только Apple не поддерживает это (даже на момент написания этой статьи) на своих устройствах (по неизвестным причинам) [они также не принимают активного участия в каких-либо обсуждениях спецификаций сервис-воркеров].
Что такое сервисный работник? По сути, это веб-воркер на стероидах. Одной из характеристик веб-воркеров является то, что все задачи веб-воркеров выполняются отдельно (асинхронно) от основного потока выполнения JavaScript (цикл событий). Эта функция помогает выполнять задачи с интенсивным использованием ЦП или памяти, например сложные вычисления, без ущерба для производительности пользовательского интерфейса веб-приложения.
Service Worker позволяет нам кэшировать (хранить в течение длительного времени) активы, такие как JavaScript, CSS, HTML, изображения, файлы шрифтов в кеше сервисного работника браузера, поэтому в следующий раз, когда пользователь загружает эту страницу, она загружается почти мгновенно. . А также, поскольку в этой стратегии кэширования браузер ищет доступность ресурсов сначала из кеша сервис-воркера, веб-страница обслуживается, даже когда она не в сети! Если какого-либо актива нет в кеше, то для его извлечения отправляется сетевой запрос.
Сервисный работник также включает push-уведомления, которые в наши дни можно увидеть на многих веб-сайтах, включая Facebook, Whatsapp в Интернете и Twitter. В первую очередь мы будем говорить об автономной функции. Это практическое руководство относится к Jekyll, однако большую часть кода сервис-воркера можно применить к любому веб-сайту.
Поскольку Jekyll обслуживает статическое содержимое ( это генератор статических сайтов, да! ), код нашего сервис-воркера будет очень простым и простым для понимания.
ДАВАЙТЕ ПРОКАЧАТЬ:
На всех соответствующих страницах выполняется следующий фрагмент скрипта. Он делает следующие вещи:
- Проверка наличия API сервис-воркера в браузере и регистрация сервис-воркера.
- Когда сервис-воркер будет активирован, поместите пользователю приятное сообщение о том, что веб-сайт готов к использованию в автономном режиме.
функция showOfflineToast() {
let offlineToast = document.querySelector('.offline-ready');
offlineToast.classList.add('активный');
setTimeout (функция () {
offlineToast.className = offlineToast.className.replace("active", "").trim();
}, 5500);
}
// (1)
если (navigator.serviceWorker) {
navigator.serviceWorker.register('/sw.js').then(function(reg) {
если (!reg.installing) вернуться;
console.log("[*] ServiceWorker устанавливается...");
var worker = reg.installing;
worker.addEventListener («изменение состояния», функция () {
если (worker.state == 'избыточный') {
console.log('[*] Ошибка установки');
}
если (worker.state == 'установлено') {
console.log('[*] Установка выполнена успешно!');
}
// (2)
if (worker.state == 'активировано' && !navigator.serviceWorker.controller) {
показатьOfflineToast();
}
});
});
} 
Вы можете добавить этот фрагмент кода в файл, скажем, serviceWorker.html внутри каталога include вашего кода Jekyll и включить его в default.html , используя жидкий механизм шаблонов Jekyll.
<!ДОКТИП HTML>
<html>
{% включает head.html %}
<тело>
{% включает заголовок.html %}
<div class="контент страницы">
<div класс="обертка">
{{ содержание }}
</div>
</div>
{% включает footer.html %}
<!-- Содержит указанный выше код в теге script-->
{% включает serviceWorker.html %}
<div class="offline-ready">Сайт готов к работе в автономном режиме</div>
</тело>
</html>
Теперь к реальному коду сервис-воркера, который творит чудеса. Этот код находится в sw.js в корне вашего кода Jekyll.
//sw.js
---
макет: ноль
---
const staticCacheName = "gdad-s-river-static-v61";
console.log("установка сервис-воркера");
константные файлыToCache = [
"/",
{% для страницы в site.html_pages %}
'{{ page.url }}',
{% конец для %}
{% для сообщения в site.posts %}
'{{ post.url }}',
{% конец для %}
// может быть автоматическим, а не ручным вводом
"/assets/images/bhavri-github-callbacks.png",
"/assets/images/bhavri-github-issues.png",
"/assets/images/jakethecake-svg-line-anime.png",
"/assets/images/svg-animated-mast-text-shapes-tweet.png",
"CSS/основной.CSS",
"/о/",
"/index.html"
];
staticCacheName — это версия кеша, которая должна обновляться каждый раз, когда я вношу некоторые изменения в кешированные ответы (например, я вношу изменения, скажем, в файл CSS или сообщение в блоге). И я просто определяю, какие запросы я хочу перехватывать и кэшировать в массиве (используется в следующем фрагменте).

//sw.js
self.addEventListener ("установить", функция (е) {
self.skipWaiting();
e.waitUntil(
caches.open(staticCacheName).then(function(cache){
вернуть cache.addAll (filesToCache);
})
)
});self.skipWaiting означает, что каждый раз, когда этот файл sw.js изменяется, более новая версия сервисного работника не должна ставиться в очередь, а должна немедленно становиться активной (можно запросить у пользователя запрос на обновление страницы с сообщением вроде Веб-страница была обновлена / изменена, нажмите «Обновить», чтобы загрузить новые сообщения или что-то еще. ), выбрасывая старую версию.

e.waitUntil цитата с веб-сайта MDN:
«Метод ExtendableEvent.waitUntil() продлевает время жизни события. В сервис-воркерах продление жизни события не позволяет браузеру завершить сервис-воркер до завершения асинхронных операций внутри события».
Я открываю кеш с именем gdad-s-river-static-v61 , который возвращает промис с именем моего кеша, а затем я вызываю cache.addAll (который использует API выборки в фоновом режиме), который извлекает все запросы в предоставленный массив и кэширует их.
К следующему фрагменту!
//sw.js
self.addEventListener («активировать», function (e) {
e.waitUntil(
caches.keys().then(function(cacheNames){
вернуть Обещание.все(
cacheNames.filter (функция (cacheName) {
return cacheName.startsWith("gdad-s-river-static-")
&& cacheName != staticCacheName;
}).карта(функция(названиекэша){
вернуть cache.delete(cacheName);
})
)SS
})
)
});Когда сервис-воркер активируется, я гарантирую, что любой сервис-воркер, версия которого не является последней, будет удалена. Например, если моя последняя версия кеша, скажем, gdad-s-river-static-v61 , а кто-то все еще использует gdad-s-river-static-v58 , при его/ее следующем посещении я хочу, чтобы этот клиент не заботился о загружая одну версию за раз, но сразу же удаляйте эту версию, чтобы установить последнюю.
//sw.js
self.addEventListener («выборка», функция (е) {
e.respondWith(
caches.match(e.request).then(function(response) {
вернуть ответ || выборка (электронный запрос);
})
)
});В событии выборки я просто говорю сервисному работнику, как реагировать на конкретный сделанный запрос (поскольку мы перехватываем полномочия, дающие ответ, сервисные работники работают только на защищенных веб-сайтах, известных как исходные https). Я говорю ему сопоставить запрос с теми, которые кэшируются в браузере, и, если он не находит этот конкретный ответ на запрос, получить его через сеть, иначе обработать его из кэша.
Тада! Сервисный работник перевел блог на базе Jekyll в автономный режим!
СЮРПРИЗ! КРУТАЯ ВЕЩЬ:
Облом: это не будет работать на устройствах iOS.
Если вы добавите файл manifest.json веб-приложения в корень проекта следующим образом:
{
"name": "гдад-с-река",
"short_name": "гдад-с-река",
"theme_color": "#2196f3",
"background_color": "#2196f3",
"дисплей": "автономный",
"Объем": "/",
"start_url": "/",
"значки": [
{
"src": "активы/изображения/favicon_images/android-icon-36x36.png",
"размеры": "36x36",
"тип": "изображение\/png",
"плотность": "0,75"
},
{
"src": "активы/изображения/favicon_images/android-icon-48x48.png",
"размеры": "48x48",
"тип": "изображение\/png",
"плотность": "1.0"
},
{
"src": "активы/изображения/favicon_images/android-icon-72x72.png",
"размеры": "72x72",
"тип": "изображение\/png",
"плотность": "1,5"
},
{
"src": "активы/изображения/favicon_images/android-icon-96x96.png",
"размеры": "96x96",
"тип": "изображение\/png",
"плотность": "2.0"
},
{
"src": "активы/изображения/favicon_images/android-icon-144x144.png",
"размеры": "144x144",
"тип": "изображение\/png",
"плотность": "3.0"
},
{
"src": "активы/изображения/favicon_images/android-icon-192x192.png",
"размеры": "192x192",
"тип": "изображение\/png",
"плотность": "4,0"
}
]
}и добавьте его в файл head.html внутри тега head,
<голова> <!-- кое-что --> <link rel="manifest" href="/manifest.json"> <!-- кое-что --> </голова>
Затем, при втором посещении вашего веб-сайта (в течение 5 минут), пользователю будет предложено добавить ваш веб-сайт на главный экран (чтобы он отображался со значком, как и в других нативных приложениях), с которым вы будете работать так же, как приложение.

РЕСУРСЫ
- Подробную информацию об автономных функциях сервис-воркера и стратегиях кэширования можно найти в оффлайн-поваренной книге этого замечательного Джейка Арчибальда.
- Очень подробный бесплатный курс Udacity обо всем, что вам нужно знать о сервис-воркерах и IndexDB.
Считаете ли вы эту статью в блоге Jekyll интересной и полезной? Не забывайте делиться своими мнениями и отзывами.
Читайте также : Ecosia — поисковая система, которая сажает деревья
