Service Worker в экосистеме Quasar используется для реализации возможностей прогрессивных веб-приложений (PWA): офлайн-доступ, кэширование ресурсов, ускорение загрузки и управление обновлениями. В основе лежит стандартный API браузера, однако Quasar предоставляет удобную интеграцию через режим PWA.
Одной из ключевых задач является корректное обновление Service Worker, поскольку от этого зависит актуальность кода приложения и пользовательский опыт.
Service Worker проходит несколько этапов:
Особенность: новая версия Service Worker не активируется сразу, если предыдущая ещё используется.
При выпуске новой версии приложения возникает ситуация:
waitingЭто приводит к тому, что пользователь не получает обновление до перезагрузки страницы или закрытия вкладки.
Стандартное поведение:
Плюсы:
Минусы:
Используется метод:
self.skipWaiting()
Позволяет новой версии Service Worker сразу перейти в состояние
activate.
Также необходимо:
self.clients.claim()
Это позволяет новому Service Worker сразу начать контролировать все страницы.
Плюсы:
Минусы:
Наиболее распространённый подход:
В Quasar режим PWA использует register-service-worker
или встроенные механизмы через @quasar/app.
Файл регистрации обычно находится:
src-pwa/register-service-worker.js
Пример обработки:
import { register } from 'register-service-worker'
register('/service-worker.js', {
updated(registration) {
console.log('Новая версия доступна')
if (confirm('Доступно обновление. Перезагрузить?')) {
registration.waiting.postMessage({ type: 'SKIP_WAITING' })
}
}
})
В файле Service Worker:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting()
}
})
После активации нового Service Worker необходимо обновить страницу:
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload()
})
Это гарантирует загрузку новой версии ресурсов.
Quasar использует Workbox для генерации Service Worker.
Файл конфигурации:
quasar.config.js
Пример:
pwa: {
workboxMode: 'GenerateSW',
workboxOptions: {
skipWaiting: false,
clientsClaim: false
}
}
При использовании InjectManifest:
self.addEventListener('install', (event) => {
self.skipWaiting()
})
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim())
})
Важно учитывать стратегию кэширования:
Неправильная стратегия может привести к:
Рекомендуется использовать версионирование:
const CACHE_NAME = 'app-v2'
При активации:
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(
keys.map((key) => {
if (key !== CACHE_NAME) {
return caches.delete(key)
}
})
)
)
)
})
На практике используются:
Важно:
Пример с использованием компонентов Quasar:
this.$q.notify({
message: 'Доступна новая версия',
actions: [
{
label: 'Обновить',
handler: () => {
registration.waiting.postMessage({ type: 'SKIP_WAITING' })
}
}
]
})
1. Отсутствие reload после обновления → пользователь остаётся на старом UI
2. skipWaiting без контроля → возможны баги состояния
3. Неверное кэширование API → устаревшие данные
4. Несинхронизированные версии frontend/backend → ошибки при запросах
skipWaiting без UXИнструменты:
Команды в консоли:
navigator.serviceWorker.getRegistrations().then(r => console.log(r))
Возможна реализация:
Пример:
if (appVersion !== serverVersion) {
showUpdateDialog()
}
Рекомендуется:
Service Worker работает только через HTTPS.
Исключения:
Эффективное управление обновлением Service Worker — критический аспект стабильности и предсказуемости PWA-приложения на Quasar.