Стратегия cacheFirst относится к числу базовых подходов работы Service Worker с кэшем. Её основная идея — приоритетное использование данных из кэша перед обращением к сети. Это позволяет значительно ускорить загрузку ресурсов и уменьшить зависимость от качества интернет-соединения.
Алгоритм работы:
Такой подход особенно эффективен для статических ресурсов, которые редко изменяются.
Библиотека sw-precache автоматически генерирует Service Worker с преднастроенными стратегиями кэширования. Обработчик cacheFirst применяется для:
Главная цель — максимально быстрое получение ресурса без ожидания сети.
Пример реализации стратегии вручную внутри Service Worker:
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
if (response) {
return response;
}
return fetch(event.request).then(function(networkResponse) {
return caches.open('runtime-cache').then(function(cache) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
});
})
);
});
Ключевые элементы:
caches.match() — поиск ресурса в кэшеfetch() — сетевой запрос при отсутствии кэшаcache.put() — сохранение ответаВ sw-precache стратегия задаётся через параметр
runtimeCaching.
Пример конфигурации:
module.exports = {
runtimeCaching: [
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/,
handler: 'cacheFirst'
}
]
};
Здесь:
urlPattern — регулярное выражение для выбора
ресурсовhandler: 'cacheFirst' — применение стратегииВозможности настройки позволяют контролировать поведение кэша:
module.exports = {
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\//,
handler: 'cacheFirst',
options: {
cacheName: 'google-fonts',
cacheExpiration: {
maxEntries: 30,
maxAgeSeconds: 60 * 60 * 24 * 365
}
}
}
]
};
Параметры:
Ограничение стратегии cacheFirst заключается в том, что:
Это приводит к проблеме устаревших данных.
Способы решения:
Версионирование файлов:
app.js?v=2Использование хешей:
app.8f3a1c.jsОграничение времени жизни через
maxAgeSeconds
| Стратегия | Приоритет | Использование сети | Актуальность данных |
|---|---|---|---|
| cacheFirst | Кэш | Только при промахе | Низкая |
| networkFirst | Сеть | Всегда | Высокая |
| staleWhileRevalidate | Кэш + обновление | Фоновая | Средняя |
cacheFirst обеспечивает максимальную скорость, но уступает в актуальности.
1. Изображения
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/,
handler: 'cacheFirst'
}
2. Шрифты
{
urlPattern: /^https:\/\/fonts\./,
handler: 'cacheFirst'
}
3. JS и CSS
{
urlPattern: /\.(?:js|css)$/,
handler: 'cacheFirst'
}
Без ограничений cacheFirst может привести к переполнению хранилища.
Рекомендуемые настройки:
options: {
cacheExpiration: {
maxEntries: 50,
maxAgeSeconds: 7 * 24 * 60 * 60
}
}
Подходы:
Преимущества:
Недостатки:
cacheFirst обеспечивает:
Ограничения:
На практике cacheFirst редко используется изолированно.
Типичная схема:
runtimeCaching: [
{
urlPattern: /\.(?:js|css|png|jpg)$/,
handler: 'cacheFirst'
},
{
urlPattern: /\/api\//,
handler: 'networkFirst'
}
]
Подход:
1. Кэширование HTML Использование cacheFirst для HTML может привести к устаревшему интерфейсу.
2. Отсутствие версионирования Файлы не обновляются после деплоя.
3. Переполнение кэша Без ограничений хранилище быстро заполняется.
4. Неправильные urlPattern Слишком широкие шаблоны могут кэшировать нежелательные ресурсы.
При генерации Service Worker библиотека:
Пример сгенерированного фрагмента:
self.addEventListener('fetch', function(event) {
if (event.request.url.match(/\.png$/)) {
event.respondWith(
caches.open('cache-name').then(function(cache) {
return cache.match(event.request).then(function(response) {
return response || fetch(event.request).then(function(resp) {
cache.put(event.request, resp.clone());
return resp;
});
});
})
);
}
});
Инструменты:
Проверка:
from ServiceWorker или
from disk cacheПример удаления старых кэшей:
self.addEventListener('activate', function(event) {
const whitelist = ['cache-v2'];
event.waitUntil(
caches.keys().then(function(keys) {
return Promise.all(
keys.map(function(key) {
if (!whitelist.includes(key)) {
return caches.delete(key);
}
})
);
})
);
});
Стратегия занимает ключевое место в построении offline-first приложений, обеспечивая:
При правильной настройке cacheFirst становится основой производительного и отзывчивого веб-приложения.