Cache API: основы

Урок знакомит с Cache API — хранилищем пар «запрос → ответ», которым пользуется Service Worker.

Cache API — это браузерное хранилище, которое сохраняет HTTP-ответы, привязывая их к запросам. Доступно через глобальный объект caches.

Чем Cache API отличается от других хранилищ

Cache API хранит не строки и не объекты, а целые пары запрос → ответ (объекты Request и Response). Это идеально для офлайна: вы сохраняете ответ на запрос /styles.css, и потом, когда сети нет, отдаёте этот сохранённый ответ. В отличие от localStorage, Cache API асинхронный (работает через Promise) и вмещает гораздо больше данных.

Основные операции

// открыть (или создать) именованный кеш
const cache = await caches.open('app-v1');

// положить заранее перечисленные ресурсы
await cache.addAll(['/', '/styles.css', '/app.js']);

// положить один ответ вручную
await cache.put('/data.json', responseObject);

// найти ответ в кеше
const response = await cache.match('/styles.css');

// найти в любом из кешей
const any = await caches.match('/styles.css');

Код помечен language-text, потому что Cache API доступен только в браузерном контексте Service Worker и не исполняется в песочнице.

Именованные кеши

Кеши именуют, чтобы управлять версиями. Типичный приём — включить версию в имя: app-v1, app-v2. При выходе новой версии меняете имя, кешируете заново, а старый кеш удаляете на activate. Можно держать несколько кешей с разным назначением:

КешЧто в нём
static-v1оболочка: HTML, CSS, JS, иконки
images-v1картинки контента
api-v1ответы API

Как работает под капотом match

Когда вы вызываете cache.match(request), браузер ищет в кеше сохранённый ответ для этого запроса. Сопоставление идёт по URL (и, при необходимости, по методу и заголовкам). Если совпадение найдено — возвращается клон сохранённого Response, причём мгновенно, без обращения к сети. Если нет — возвращается undefined, и вы решаете, что делать дальше (например, сходить в сеть).

Важный нюанс: Response одноразовый

Объект Response можно «прочитать» только один раз (его тело — поток). Если вы хотите и отдать ответ странице, и положить его в кеш, нужно сделать копию через response.clone() до того, как отдадите оригинал.

const response = await fetch(request);
cache.put(request, response.clone()); // в кеш — копию
return response;                       // оригинал — странице

Частые ошибки

  • Использовать один Response дважды. Без clone() второе чтение даст ошибку «body already used».
  • Не версионировать имя кеша. Старые ответы будут жить вечно, и обновления не подхватятся.
  • Путать caches.match и cache.match. Первый ищет во всех кешах, второй — в конкретном.

Итоги

  • Cache API хранит пары запрос → ответ, доступен через caches, асинхронный.
  • Основные методы: caches.open, cache.addAll, cache.put, cache.match.
  • Кеши именуют с версией для управления обновлениями.
  • Response одноразовый — для кеша делайте clone().
Проверьте себя
1. Что хранит Cache API?
AТолько строки, как localStorage
BПары запрос (Request) → ответ (Response)
CТолько картинки
DJavaScript-объекты
2. Зачем нужен response.clone() перед сохранением в кеш?
AДля ускорения
BТело Response можно прочитать только один раз, поэтому в кеш кладут копию, а оригинал отдают странице
CЧтобы зашифровать ответ
DЧтобы уменьшить размер
3. Чем отличаются caches.match и cache.match?
AНичем
Bcaches.match ищет во всех кешах, cache.match — в одном конкретном
Ccache.match быстрее
Dcaches.match работает офлайн, а cache.match — нет