Ответ
Начни с выбора стратегии кэширования. Service Worker — ключевая технология для оффлайн-работы. Вот базовые шаги:
- Зарегистрируй Service Worker в основном JS-файле:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
- В файле sw.js определи кэшируемые ресурсы и стратегию:
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles.css',
'/script.js',
'/fallback.html'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
- Реализуй стратегию "Cache falling back to network":
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
Дополнительно:
- Используй IndexedDB для хранения данных
- Добавь манифест веб-приложения
- Продумай механизм синхронизации при восстановлении соединения
- Протестируй в DevTools → Application → Service Workers
Ответ 18+ 🔞
Ну, слушай, если хочешь, чтобы твоё веб-приложение не вырубалось, как только у пользователя интернет капризничает, то без Service Worker'а — нихуя не выйдет. Это, блядь, как подпольный склад в браузере. Начинаем с главного — выбора стратегии, как этот склад работать будет.
Первым делом, в своём основном JavaScript'е надо этого работничка зарегистрировать. Пишем проверку, чтоб не облажаться на старых браузерах:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
Всё, чувак зачислен в штат. Теперь создаём ему инструкцию — файл sw.js. Тут самое интересное начинается, ёпта.
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles.css',
'/script.js',
'/fallback.html'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
Смотри, что происходит: когда воркер устанавливается, он открывает кэш с именем v1 и тупо складывает туда все ресурсы из списка urlsToCache. Главное, чтобы все пути были правильные, а то будет искать и нихуя не найдёт.
А теперь, внимание, стратегия! Одна из самых простых и жизнеспособных — «Сначала кэш, потом сеть». Если в кэше лежит то, что просит страница, отдаём оттуда. Если нет — идём, сломя голову, в интернет.
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
Представь: пользователь тыкает на кнопку, а у него уже связи нет. Браузер такой: «Э, слушай, я же это уже сохранял!» — и бац, показывает из кэша. Волшебство, блядь! А если не сохранял... ну, тогда пиши пропало, будет ошибка. Но для этого и есть fallback.html в списке, чтобы хоть что-то показать.
Что ещё, сука, не забудь:
- IndexedDB — это для данных посерьёзнее. Кэш — для файлов, а туда можно юзеров, настройки, черновики складировать. Будет своя маленькая база данных прямо в браузере.
- Манифест веб-приложения (
manifest.json) — без него на мобилках не добавить иконку на главный экран. Базовый must-have для PWA. - Синхронизация — это уже высший пилотаж. Когда связь появится, нужно тихо и незаметно отправить на сервер всё, что пользователь наделал в офлайне. Механизм
Background Syncв помощь, но это отдельная история, там своя ёбаная магия. - Тестирование — не ленись, открой Chrome DevTools, вкладка «Application». Там целый раздел «Service Workers». Ты можешь его там посмотреть, заставить обновиться, сымитировать офлайн-режим и проверить, что твой кэш работает, а не просто так, для галочки.
Вот так, коротко и без лишней ебли. Главное — начать, а там уже по обстоятельствам.