Workbox предоставляет мощный инструментарий для управления
кэшированием и обработкой сетевых запросов в сервис-воркерах. Один из
важных компонентов — возможность модифицировать ответы перед их
сохранением в кэш или отправкой клиенту с помощью
плагинов. Плагин для сжатия и трансформации ответов
(Response Plugins) позволяет изменять содержимое ответа,
применяя сжатие, фильтрацию или другие трансформации данных.
Плагины Workbox представляют собой объекты с заранее определёнными методами, которые вызываются на определённых этапах жизненного цикла запроса:
cacheWillUpdate({response}) — вызывается перед
сохранением ответа в кэш, позволяет определить, сохранять его или
нет.cacheDidUpdate({cacheName, request, oldResponse, newResponse})
— уведомление о том, что кэш был обновлён.fetchDidSucceed({request, response}) — вызывается после
успешного сетевого запроса.fetchDidFail({request}) — вызывается при ошибке
сетевого запроса.Для плагина трансформации ответов ключевым методом является
cacheWillUpdate, так как он позволяет
перехватывать ответ и изменять его содержимое.
Сжатие данных перед кэшированием улучшает производительность и уменьшает объём используемого хранилища. Пример плагина для gzip-сжатия:
import {Plugin} from 'workbox-core';
const compressResponsePlugin = {
async cacheWillUpdate({response}) {
if (!response || response.status !== 200 || response.type !== 'basic') {
return null;
}
const clonedResponse = response.clone();
const data = await clonedResponse.arrayBuffer();
// Пример сжатия с использованием pako
import('pako').then(pako => {
const compressed = pako.gzip(new Uint8Array(data));
return new Response(compressed, {
headers: {
'Content-Type': 'application/octet-stream',
'Content-Encoding': 'gzip',
},
});
});
}
};
Ключевые моменты:
Response является потоковым.Content-Encoding, чтобы клиент
понимал, что данные сжаты.Response, который
попадёт в кэш.Иногда требуется изменить данные перед кэшированием, например, фильтровать поля или нормализовать объекты:
const transformJsonPlugin = {
async cacheWillUpdate({response}) {
if (!response || response.status !== 200) return null;
const clonedResponse = response.clone();
const jsonData = await clonedResponse.json();
// Трансформация: оставляем только нужные поля
const transformedData = jsonData.map(item => ({
id: item.id,
title: item.title
}));
return new Response(JSON.stringify(transformedData), {
headers: {'Content-Type': 'application/json'}
});
}
};
Особенности:
json() для работы с телом
ответа.Response с
обновлённым содержимым и корректными заголовками.StaleWhileRevalidate, CacheFirst,
NetworkFirst).Плагины интегрируются в стратегии кэширования Workbox через массив
plugins:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(
({request}) => request.destination === 'script',
new StaleWhileRevalidate({
cacheName: 'js-cache',
plugins: [compressResponsePlugin, transformJsonPlugin]
})
);
Принципы работы:
cacheWillUpdate определяет, что
попадёт в кэш.При работе с плагинами необходимо учитывать, что любые исключения могут прервать процесс кэширования. Поэтому рекомендуется:
try-catch внутри методов плагина.null, если ответ не подходит для
трансформации.Пример безопасной трансформации:
const safeTransformPlugin = {
async cacheWillUpdate({response}) {
try {
const cloned = response.clone();
const data = await cloned.json();
// Простая фильтрация
const filtered = data.filter(item => item.active);
return new Response(JSON.stringify(filtered), {
headers: {'Content-Type': 'application/json'}
});
} catch (e) {
console.error('Ошибка трансформации:', e);
return null;
}
}
};
Плагин для сжатия и трансформации ответов позволяет:
Использование таких плагинов повышает гибкость и эффективность стратегий Workbox, позволяя создавать быстрые и компактные Progressive Web Apps.