Кэширование в браузере: Cache-Control, ETag и настройка CDN

性能优化

Два уровня HTTP-кэширования

Браузер запрашивает ресурс
      ↓
① Строгий кэш (без обращения к серверу)
   Cache-Control: max-age=31536000
      ↓ истёк
② Валидационный кэш (спросить сервер, изменился ли ресурс)
   ETag / Last-Modified → 304 Not Modified
      ↓ ресурс изменён
③ Получить новый ресурс с сервера → 200 OK

Директивы Cache-Control

Директива Значение Пример использования
max-age=N Использовать кэш N секунд JS/CSS (1 год)
s-maxage=N CDN кэширует N секунд HTML (1 день)
no-cache Ревалидировать ETag каждый раз Ответы API
no-store Без кэширования вообще Конфиденциальные данные
immutable Содержимое никогда не меняется Ресурсы с хеш-именами
stale-while-revalidate=N Отдавать устаревшее N секунд при ревалидации i18n JSON

Конфигурация кэша ToolsKu

# _next/static/chunks/app-abc123.js
Cache-Control: public, max-age=31536000, immutable

# /ru/pdf/merge/index.html
Cache-Control: public, max-age=3600, s-maxage=86400

# /i18n/toolClients/ru.json
Cache-Control: public, max-age=86400, stale-while-revalidate=604800

Валидационное кэширование ETag

# Первый запрос
GET /api/config HTTP/1.1
→ 200 OK
   ETag: "abc123"
   Cache-Control: no-cache

# Последующий запрос
GET /api/config HTTP/1.1
   If-None-Match: "abc123"
→ 304 Not Modified (пустое тело, экономит трафик)

ETag генерируется на основе хеша содержимого. Неизменённое содержимое возвращает 304, и браузер использует локальную копию.


Архитектура кэша CDN

ToolsKu развёрнут на Alibaba Cloud OSS + CDN:

Пользователь запрашивает https://www.toolsku.com/ru/
      ↓
Краевой узел CDN (Пекин / Шанхай / Гуанчжоу)
      ↓ попадание в кэш → прямой ответ (TTFB ~20ms)
      ↓ промах кэша
Источник OSS (Пекин)
      ↓ возвращает ресурс + заполняет кэш CDN
CDN → пользователь

Дизайн ключа кэша

Ключи CDN обычно — URL + строка запроса. Обратите внимание на:

  • ?v=123 и ?v=456 — разные записи кэша
  • Запросы с Accept-Language могут разделить кэш (заголовок Vary)
  • ToolsKu использует локали на основе пути (/zh-CN/, /en/), чтобы избежать проблем с Vary

Распространённые ошибки кэширования

1. JS обновлён, но пользователи видят старую сборку

Причина: Старый JS строго закэширован; новый HTML ссылается на новые имена файлов, но старый JS остаётся в кэше.

Решение: Имена файлов с хешем содержимого (по умолчанию в Next.js _next/static/chunks/app-[hash].js). Изменение содержимого → изменение хеша → естественная инвалидация.

2. Кэш HTML скрывает свежий контент

Решение: Более короткий max-age + s-maxage для HTML или активная очистка через API обновления CDN.

3. Кэш Service Worker vs HTTP-кэш

Обработчик fetch Service Worker может перехватывать все запросы — приоритет над HTTP-кэшем. Увеличивайте версию кэша при обновлениях SW и удаляйте старые кэши.


Инструменты отладки кэша

  1. Chrome DevTools → Network: Столбец Size ((disk cache) / (memory cache) / фактический размер)
  2. Заголовки ответа: Проверить Cache-Control, ETag, Age
  3. ToolsKu Справочник кодов состояния HTTP: Понимание 200, 304, 404 и т.д.

Итоги

Надёжное кэширование — основа веб-производительности. Строгий кэш + валидационный кэш + краевые узлы CDN дают ToolsKu TTFB около ~50мс при первой отрисовке. Понимание Cache-Control и ETag — фундаментальная работа над производительностью фронтенда.

Попробуйте эти локальные браузерные инструменты — регистрация не требуется →

#HTTP缓存#CDN#Cache-Control#ETag#性能优化