Service Workers представляют собой мощный инструмент для управления кэшированием ресурсов, работы в офлайн-режиме и фоновых задач в веб-приложениях. Stimulus, как фреймворк для создания динамических интерфейсов, может эффективно интегрироваться с Service Workers, обеспечивая реактивное управление состоянием страниц и компонент.
Регистрация Service Worker осуществляется через стандартный API браузера. В контексте Stimulus это удобно делать в контроллере, который инициализируется при загрузке страницы. Пример базовой регистрации:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
connect() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker зарегистрирован с областью:', registration.scope);
})
.catch(error => {
console.error('Ошибка при регистрации Service Worker:', error);
});
}
}
}
Ключевые моменты:
'serviceWorker' in navigator необходима для
обеспечения совместимости с браузерами, которые не поддерживают Service
Workers.register возвращает промис с объектом
регистрации, который содержит информацию о scope и состоянии Service
Worker.Service Worker поддерживает несколько жизненно важных событий:
Пример Service Worker с кэшированием:
const CACHE_NAME = 'my-app-cache-v1';
const URLS_TO_CACHE = [
'/',
'/styles.css',
'/script.js',
'/logo.png'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(URLS_TO_CACHE))
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.filter(name => name !== CACHE_NAME)
.map(name => caches.delete(name))
);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
Особенности:
event.waitUntil гарантирует, что установка или
активация завершится только после выполнения всех асинхронных
задач.caches.match позволяет вернуть
закэшированную версию ресурса или обратиться к сети при его
отсутствии.Stimulus контроллер может взаимодействовать с Service Worker, например, для уведомления пользователей о доступности обновлений:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
connect() {
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.addEventListener('message', event => {
if (event.data === 'update-available') {
console.log('Доступно обновление приложения');
// Можно показать уведомление или автоматически обновить страницу
}
});
}
}
triggerUpdate() {
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage('skipWaiting');
}
}
}
Важные детали:
postMessage и обработку события
message.Для динамических данных, таких как API-запросы, Service Worker может применять стратегию stale-while-revalidate:
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
event.respondWith(
caches.open('dynamic-cache').then(cache => {
return cache.match(event.request).then(response => {
const fetchPromise = fetch(event.request).then(networkResponse => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return response || fetchPromise;
});
})
);
}
});
Принципы работы:
Для разработки и отладки важно управлять обновлением Service Worker:
skipWaiting() внутри Service Worker и сообщение от
контроллера Stimulus для перезагрузки страницы.Интеграция Stimulus с Service Worker позволяет создавать быстрые, отзывчивые веб-приложения с поддержкой офлайн-режима и эффективным кэшированием ресурсов, сохраняя при этом простую и модульную архитектуру.