Back

Основы кэширования, которые должен знать каждый веб-разработчик

Основы кэширования, которые должен знать каждый веб-разработчик

Ваши пользователи только что нажали на кнопку, и три секунды ничего не происходило. Запрос к базе данных выполнен, сервер ответил, но те же данные, которые загружались вчера, снова должны были пройти через весь интернет. Именно эту проблему решает кэширование.

Понимание основ HTTP-кэширования не является опциональным для фронтенд-разработчиков. Это разница между отзывчивым приложением и тем, которое кажется сломанным. Это руководство охватывает то, что вам нужно знать о браузерном кэше и CDN-кэше, заголовках Cache-Control и механизмах валидации, таких как ETag и Last-Modified.

Ключевые выводы

  • Устанавливайте явные заголовки Cache-Control для каждого ответа, чтобы избежать непредсказуемой эвристики браузера.
  • Используйте большие значения max-age в паре с cache busting (именами файлов с хешем содержимого) для статических ресурсов.
  • Используйте no-cache с ETag или Last-Modified для контента, который должен оставаться актуальным.
  • Всегда помечайте персонализированный или аутентифицированный контент как private, чтобы предотвратить утечку данных через общие кэши.

Что такое кэширование и почему это важно

Кэширование сохраняет копию данных ближе к месту, где они нужны. Когда ваш браузер запрашивает изображение, он может сохранить это изображение локально. Следующий запрос полностью пропускает сеть.

Прирост производительности впечатляющий. Например, запрос к базе данных может занять десятки миллисекунд, в то время как чтение из браузерного кэша обычно происходит практически мгновенно и полностью избегает сетевого обмена.

Кэширование обеспечивает три основных преимущества:

  • Снижение задержки: Данные проходят меньшие расстояния.
  • Снижение нагрузки на сервер: Меньше запросов достигает вашего origin-сервера.
  • Улучшение пользовательского опыта: Страницы загружаются быстрее при повторных посещениях.

Понимание уровней кэширования

Запросы проходят через несколько уровней кэширования, прежде чем достичь вашего сервера. Каждый уровень служит своей цели.

Браузерный кэш (приватный кэш)

Браузерный кэш находится на устройстве пользователя. Он хранит ответы, которые должен видеть только этот пользователь. Когда вы помечаете ответ как private, он остается здесь и никогда не передается другим пользователям.

Сюда относится персонализированный контент — профили пользователей, аутентифицированные API-ответы, всё, что привязано к конкретной сессии.

CDN-кэш (общий кэш)

CDN-кэш находится между пользователями и вашим origin-сервером, распределенный по географическим локациям. Когда пользователь в Токио запрашивает ваш JavaScript-бандл, CDN отдает его с ближайшего edge-сервера вместо вашего центра обработки данных.

CDN отлично справляются с кэшированием статических ресурсов: изображений, CSS, JavaScript и шрифтов. Они также могут кэшировать публичные API-ответы, хотя это требует тщательной настройки.

Серверное кэширование

Помимо HTTP-кэширования, серверы часто поддерживают собственные кэши, используя инструменты вроде Redis или Memcached. Как фронтенд-разработчик, вы не будете настраивать их напрямую, но понимание их существования помогает понять, почему некоторые API-ответы быстрее других.

Заголовки Cache-Control: основные директивы

Заголовок Cache-Control сообщает кэшам, как обрабатывать ответы. Это директивы, которые вы будете использовать чаще всего:

ДирективаЗначение
max-age=3600Кэшировать на 3600 секунд (1 час)
no-cacheСохранить, но ревалидировать перед использованием
no-storeНе сохранять этот ответ нигде
privateТолько браузерный кэш может хранить это
publicЛюбой кэш может хранить это

Распространенная ошибка: no-cache не означает «не кэшировать». Это означает «всегда проверять с сервером перед использованием кэшированной копии». Используйте no-store, когда вам действительно нужно полное отсутствие кэширования.

Для статических ресурсов с хешированными именами файлов используйте агрессивное кэширование:

Cache-Control: public, max-age=31536000

Для HTML-страниц, которые часто меняются (и особенно для чувствительного или высокодинамичного контента):

Cache-Control: no-cache, private

ETag и Last-Modified: механизмы валидации

Когда кэшированный контент истекает, браузерам не всегда нужно загружать всё заново. Заголовки валидации обеспечивают эффективную ревалидацию.

Last-Modified содержит временную метку. При последующих запросах браузер отправляет заголовок If-Modified-Since с этой временной меткой. Если ничего не изменилось, сервер возвращает 304 Not Modified — без тела, минимальная пропускная способность.

ETag содержит уникальный идентификатор (часто хеш содержимого). При последующих запросах браузер отправляет заголовок If-None-Match с этим идентификатором. Тот же результат: 304, если содержимое не изменилось.

ETag более точные, чем временные метки, потому что они обнаруживают фактические изменения содержимого, а не только время модификации файла. Файл может быть пересохранен без изменения содержимого, обновив временную метку, но не ETag.

Cache busting для статических ресурсов

Вы хотите, чтобы статические ресурсы кэшировались как можно дольше, но вам также нужно, чтобы пользователи получали обновления при развертывании. Cache busting решает это, изменяя URL при изменении содержимого.

Современные инструменты сборки добавляют хеши содержимого к именам файлов:

bundle.a1b2c3d4.js
styles.e5f6g7h8.css

Когда вы разворачиваете новый код, хеш меняется, URL меняется, и браузеры загружают новую версию. Старые кэшированные файлы просто истекают естественным образом.

Распространенные ошибки, которых следует избегать

Публичное кэширование аутентифицированного контента: Всегда используйте private для пользовательских данных. Утечка данных одного пользователя другому через общий кэш — серьезная проблема безопасности.

Чрезмерное кэширование API-ответов: Динамические данные требуют коротких TTL или no-cache. Устаревшие цены при оформлении заказа вызывают реальные проблемы.

Забывание устанавливать заголовки: Без явных заголовков Cache-Control браузеры могут применять эвристическое кэширование на основе метаданных ответа, что может привести к поведению, которое вы не планировали.

Заключение

Кэширование — это не то, что вы настраиваете один раз и забываете. Устанавливайте явные заголовки Cache-Control для каждого ответа. Сочетайте большие значения max-age с именами файлов с хешем содержимого для статических ресурсов. Используйте no-cache вместе с ETag или Last-Modified для контента, который должен оставаться актуальным, и всегда помечайте персонализированный контент как private. Проверяйте ваши заголовки в DevTools, проверяйте поведение вашего CDN и тестируйте то, что на самом деле испытывают пользователи.

Часто задаваемые вопросы

no-cache сообщает браузеру, что он может сохранить ответ, но должен ревалидировать его с сервером перед использованием. no-store сообщает браузеру вообще не сохранять ответ. Используйте no-store для чувствительных данных, таких как банковские реквизиты, и no-cache для контента, который часто меняется, но выигрывает от условной ревалидации.

Откройте DevTools браузера, перейдите на вкладку Network и выберите любой запрос. Раздел Response Headers показывает значения Cache-Control, ETag и Last-Modified. Также обратите внимание на колонку размера. Если там написано disk cache или memory cache, ответ был получен из браузерного кэша, а не из сети.

Это зависит от данных. Публичные, редко меняющиеся данные, такие как категории продуктов, могут использовать короткие значения max-age. Пользовательские или часто меняющиеся данные должны использовать no-cache с заголовками валидации или no-store. Всегда помечайте аутентифицированные ответы как private, чтобы предотвратить отдачу CDN данных одного пользователя другому.

Хеши содержимого позволяют устанавливать очень длительное время жизни кэша для статических ресурсов, при этом мгновенно доставляя обновления. Когда содержимое файла меняется, хеш меняется, создавая новый URL, который обходит любой существующий кэш. Этот метод называется cache busting и является стандартным подходом, используемым такими инструментами, как Webpack, Vite и Rollup.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay