Как работает кэширование в HTTP?

Ответ

HTTP-кэширование — это механизм для временного хранения копий ресурсов (HTML-страниц, CSS, JavaScript, изображений) на стороне клиента (браузер) или промежуточных прокси-серверов. Его цель — значительно ускорить повторные загрузки страниц и снизить нагрузку на origin-сервер.

Основные компоненты и заголовки:

  • Cache-Control — главный заголовок для управления кэшем. Указывает директивы:

    • max-age=<seconds> — максимальное время хранения ресурса в кэше.
    • public / privatepublic разрешает кэширование на прокси, private — только в браузере пользователя.
    • no-cache — перед использованием кэшированную версию необходимо проверить на актуальность у сервера.
    • no-store — полностью запрещает кэширование.
  • Валидаторы (для проверки свежести):

    • ETag (Entity Tag): Уникальный хэш-идентификатор версии ресурса. Клиент отправляет его в заголовке If-None-Match.
    • Last-Modified: Дата последнего изменения. Клиент отправляет её в заголовке If-Modified-Since.

Типичный жизненный цикл запроса с кэшем:

  1. Первый запрос: Браузер загружает ресурс. Сервер отвечает с заголовками, например:

    HTTP/1.1 200 OK
    Cache-Control: public, max-age=3600
    ETag: "abc123"
    Last-Modified: Mon, 01 Jan 2024 12:00:00 GMT

    Браузер сохраняет ресурс и эти заголовки в своём кэше.

  2. Повторный запрос (через 30 минут): Браузер видит, что max-age=3600 (1 час) не истёк, и загружает ресурс напрямую из кэша, без сетевого запроса.

  3. Повторный запрос (через 2 часа): max-age истёк. Браузер отправляет условный запрос с валидаторами:

    GET /style.css HTTP/1.1
    Host: example.com
    If-None-Match: "abc123"
    If-Modified-Since: Mon, 01 Jan 2024 12:00:00 GMT
    • Если ресурс не изменился, сервер отвечает статусом 304 Not Modified (без тела ответа). Браузер использует кэшированную версию.
    • Если ресурс изменился, сервер отвечает 200 OK с новым содержимым и обновлёнными заголовками кэша.

Практическая польза: Правильная настройка кэширования статических ресурсов (CSS, JS, изображения) — один из ключевых факторов высокой производительности веб-сайта.

Ответ 18+ 🔞

Давай разберём эту штуку, которая, на первый взгляд, кажется хуйнёй заумной, а на деле — просто спасение от долбанных тормозов в интернете.

HTTP-кэширование, если по-простому, — это когда твой браузер или какой-нибудь промежуточный сервер-посредник не тупо каждый раз таскает одни и те же картинки, стили и скрипты по сто раз, а припрятывает их у себя на чёрный день. Цель — не насиловать основной сервер и показывать тебе всё быстро, как будто ты из 2005 года в будущее попал.

Главные герои этой драмы — заголовки:

  • Cache-Control — это, блядь, царь и бог, главный управленец. Он командует директивами:

    • max-age=<секунды> — столько времени эту хрень можно хранить, пока не протухла. Поставил max-age=3600 — значит, час живёт спокойно.
    • public / privatepublic значит «кэшируй где хочешь, хоть на прокси», а private — «только в браузере у юзера, больше никому, сволочь, не показывай».
    • no-cache — не «не кэшировать», а «перед использованием спроси у сервера, не обновилось ли чё». Хитро, да? Пиздец как хитро.
    • no-store — вот это уже «забудь и не вспоминай, удали всё, не храни нигде». Полная паранойя.
  • Валидаторы (чтобы проверять, не скисло ли):

    • ETag: Уникальный отпечаток пальца файла, типа хэш. Клиент потом тычет его серверу в морду, спрашивая: «Эй, а этот твой "abc123" ещё актуален?».
    • Last-Modified: Дата, когда файл последний раз трогали грязными ручками. Клиент её тоже припоминает.

Как это всё живёт, на примере:

  1. Первый раз (всё грустно и долго): Ты заходишь на сайт. Сервер, ишача как проклятый, отдаёт тебе стиль style.css и говорит:

    HTTP/1.1 200 OK
    Cache-Control: public, max-age=3600
    ETag: "abc123"
    Last-Modified: Mon, 01 Jan 2024 12:00:00 GMT

    Браузер, такой: «О, окей», — и кладёт файл к себе в закрома вместе с этими пометками.

  2. Через полчаса (всё охуенно быстро): Ты обновил страницу. Браузер смотрит: max-age=3600, час ещё не прошёл. И он, не долго думая, достаёт файл прямо из своего кэша, без единого запроса в сеть. Вообще тишина, красота. Скорость — ебать в сраку реактивный истребитель.

  3. Через два часа (пора проверить): Время жизни (max-age) вышло. Файл вроде как «условно протух». Браузер не грузит его сразу, а делает умный, условный запрос, показывая серверу те самые валидаторы:

    GET /style.css HTTP/1.1
    Host: example.com
    If-None-Match: "abc123"
    If-Modified-Since: Mon, 01 Jan 2024 12:00:00 GMT

    По смыслу это: «Чувак, у меня тут есть версия с тэгом "abc123" от первого января. Она ещё годная?».

    • Если файл не менялся: Сервер лениво отвечает: 304 Not Modified (типа «не хуя нового, используй свою старую»). Тело ответа пустое, экономия трафика — овердохуищная.
    • Если файл поменяли: Сервер говорит: 200 OK и шлёт новую, свежую версию файла со всеми обновлёнными заголовками. Старую — в помойку, живём дальше.

Суть в чём, блядь? Если правильно настроить эту магию для статики — картинок, CSS и JS — то сайт будет летать, серверу легче, пользователям приятнее. А если проебаться с настройками, то будешь каждый раз грузить гигабайты одних и тех же гифок с котиками, и все будут тебя ненавидеть. Вот и вся наука, ёпта.