Workbox предоставляет мощный набор инструментов для управления кэшированием и обработкой сетевых запросов в сервис-воркерах. Одной из ключевых возможностей является сборка ответа из нескольких источников, что позволяет комбинировать данные из кэша, сетевых запросов и даже динамически создаваемого контента. Это особенно актуально для сложных приложений, где требуется объединять ресурсы с разных серверов или формировать единый ответ из разных частей.
CacheFirst и NetworkFirst в комбинацииДля объединения данных из кэша и сети часто применяют стратегию
смешанного кэширования. Workbox позволяет создавать кастомные маршруты с
использованием registerRoute и функций-обработчиков,
возвращающих промисы с объектом Response.
Пример стратегии объединения кэшированных и сетевых данных:
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst } from 'workbox-strategies';
registerRoute(
({ url }) => url.pathname.startsWith('/api/data'),
async ({ request }) => {
const cacheStrategy = new CacheFirst({
cacheName: 'api-cache',
});
const networkStrategy = new NetworkFirst({
cacheName: 'api-network-cache',
});
const [cacheResponse, networkResponse] = await Promise.all([
cacheStrategy.handle({ request }),
networkStrategy.handle({ request })
]);
let mergedData = {};
if (cacheResponse) {
const cacheJson = await cacheResponse.json();
Object.assign(mergedData, cacheJson);
}
if (networkResponse) {
const networkJson = await networkResponse.json();
Object.assign(mergedData, networkJson);
}
return new Response(JSON.stringify(mergedData), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Ключевые моменты:
Promise.all позволяет параллельно получить ответ из
кэша и сети.Object.assign или другой метод объединения данных
позволяет гибко комбинировать разные источники.Response должен иметь корректный
тип контента (application/json для JSON).Workbox поддерживает возможность комбинировать не только один источник кэша и один сетевой ресурс, но и несколько разных эндпоинтов. Это делается через асинхронные функции внутри обработчика маршрута.
Пример запроса к нескольким API и объединения результатов:
registerRoute(
({ url }) => url.pathname === '/api/combined',
async () => {
const urls = ['/api/user', '/api/settings', '/api/notifications'];
const responses = await Promise.all(urls.map(url => fetch(url).then(res => res.json())));
const combined = responses.reduce((acc, data) => Object.assign(acc, data), {});
return new Response(JSON.stringify(combined), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Особенности подхода:
fetch позволяет напрямую обращаться к сети без
использования стратегии кэширования, если необходимы актуальные
данные.reduce аккуратно объединяет объекты в один, сохраняя
структуру данных.При сборке данных из нескольких источников важно учитывать приоритет
сетевых запросов и обработку таймаутов. Workbox предоставляет удобный
инструмент TimeoutPlugin, который позволяет ограничивать
время ожидания ответа от кэша или сети:
import { NetworkFirst } from 'workbox-strategies';
import { TimeoutPlugin } from 'workbox-expiration';
const networkStrategy = new NetworkFirst({
cacheName: 'api-network-cache',
plugins: [
new TimeoutPlugin({
maxAgeSeconds: 5,
}),
],
});
Особенности:
В сложных приложениях иногда требуется кэшировать не весь
объединённый ответ, а только его части. Для этого Workbox позволяет
работать с Cache API напрямую внутри обработчика
маршрута:
registerRoute(
({ url }) => url.pathname.startsWith('/api/data'),
async ({ request }) => {
const cache = await caches.open('partial-cache');
const userResponse = await fetch('/api/user');
cache.put('/api/user', userResponse.clone());
const settingsResponse = await fetch('/api/settings');
cache.put('/api/settings', settingsResponse.clone());
const combined = {
user: await userResponse.json(),
settings: await settingsResponse.json()
};
return new Response(JSON.stringify(combined), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Преимущества такого подхода:
Использование Workbox для комбинирования нескольких источников данных позволяет создавать сложные, отзывчивые и кэшируемые приложения. Стратегии могут варьироваться от простого объединения кэша и сети до сложного динамического слияния нескольких API с управлением таймаутами, приоритетами и частичным кэшированием. Гибкость Workbox делает такие подходы масштабируемыми и легко поддерживаемыми в больших приложениях.