Стратегия networkFirst в библиотеке
sw-precache реализует модель, при которой первичный
источник данных — сеть, а кэш используется как резервный вариант при
недоступности сети или превышении времени ожидания. Такой подход
особенно эффективен для динамического контента, где актуальность данных
критична.
Алгоритм networkFirst можно описать следующим
образом:
При поступлении запроса Service Worker пытается получить ответ из сети.
Если сетевой запрос успешен:
Если сетевой запрос завершился ошибкой (например, отсутствует соединение):
Одной из важных особенностей networkFirst является
возможность задания времени ожидания сети. Если ответ от сервера не
получен в течение заданного интервала:
Настройка стратегии networkFirst осуществляется через
параметр runtimeCaching в конфигурации:
module.exports = {
runtimeCaching: [
{
urlPattern: /\/api\/.*$/,
handler: 'networkFirst',
options: {
cache: {
name: 'api-cache'
},
networkTimeoutSeconds: 3
}
}
]
};
urlPatternОпределяет, какие запросы будут обрабатываться стратегией. Поддерживает регулярные выражения.
handler: 'networkFirst'Указывает на использование стратегии с приоритетом сети.
options.cache.nameИмя кэша, в котором будут храниться ответы.
options.networkTimeoutSecondsМаксимальное время ожидания ответа от сети. После истечения этого времени используется кэш.
Актуальность данных имеет первостепенное значение:
urlPattern: /\/api\/data/,
handler: 'networkFirst'
При использовании SPA или SSR важно загружать свежую версию страницы:
urlPattern: /\.html$/,
handler: 'networkFirst'
Данные профиля, сообщения, уведомления:
| Стратегия | Приоритет | Использование кэша |
|---|---|---|
cacheFirst |
Кэш | Основной источник |
networkFirst |
Сеть | Резерв |
fastest |
Оба | Кто быстрее |
networkOnly |
Сеть | Не используется |
В networkFirst важно контролировать, какие ответы
сохраняются:
options: {
cache: {
name: 'dynamic-cache',
maxEntries: 50,
maxAgeSeconds: 300
}
}
Это предотвращает переполнение хранилища и устаревание данных.
Если ни сеть, ни кэш не дали результата:
Пример расширенной логики:
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request)
.then(response => {
return caches.open('dynamic').then(cache => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => {
return caches.match(event.request);
})
);
});
Позволяет избежать долгого ожидания медленной сети:
networkTimeoutSeconds: 2
Разные типы ресурсов должны храниться отдельно:
api-cachehtml-cacheimage-cacheПредотвращает рост использования памяти.
Приоритет сети может привести к медленной загрузке, если соединение нестабильно.
Если сеть недоступна, пользователь получает устаревшие данные.
Требуется баланс между таймаутами, размером кэша и частотой обновлений.
Можно использовать networkFirst только для API, а для
статических ресурсов — cacheFirst.
Разные стратегии в зависимости от типа запроса:
runtimeCaching: [
{
urlPattern: /\/api\//,
handler: 'networkFirst'
},
{
urlPattern: /\.(js|css)$/,
handler: 'cacheFirst'
}
]
networkFirst для динамического
контента;networkTimeoutSeconds;networkFirst в sw-precache реализуется через
последовательную попытку:
fetch()cache.match()С сохранением успешных сетевых ответов через:
cache.put(request, response.clone());
Клонирование необходимо, так как поток ответа может быть использован только один раз.
Такой подход обеспечивает баланс между актуальностью данных и устойчивостью приложения к сетевым сбоям.