Перейти к содержанию

immutable: модуль NGINX для установки неизменяемого кеширования статических ресурсов

Установка на Debian/Ubuntu

Эти документы относятся к пакету APT nginx-module-immutable, предоставляемому репозиторием GetPageSpeed Extras.

  1. Настройте репозиторий APT, как описано в настройке APT репозитория.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-immutable
Показать дистрибутивы и архитектуры
| Дистрибутив | Версия            | Компонент   | Архитектуры     |
|-------------|-------------------|-------------|------------------|
| debian      | bookworm          | main        | amd64, arm64     |
| debian      | bookworm-mainline | main        | amd64, arm64     |
| debian      | trixie            | main        | amd64, arm64     |
| debian      | trixie-mainline   | main        | amd64, arm64     |
| ubuntu      | focal             | main        | amd64, arm64     |
| ubuntu      | focal-mainline    | main        | amd64, arm64     |
| ubuntu      | jammy             | main        | amd64, arm64     |
| ubuntu      | jammy-mainline    | main        | amd64, arm64     |
| ubuntu      | noble             | main        | amd64, arm64     |
| ubuntu      | noble-mainline    | main        | amd64, arm64     |

Coverity Scan

Этот небольшой модуль NGINX может помочь улучшить кеширование ваших общедоступных статических ресурсов, устанавливая долгосрочный срок истечения с атрибутом immutable.

Целевая аудитория

Веб-сайты и фреймворки, которые полагаются на схему управления кешем:

  • статические ресурсы включают версии/хеши в их URL, не изменяя сами ресурсы
  • при необходимости, обновляются ресурсы с новыми версиями, которые имеют новые номера версий/хеши, чтобы их URL были разными

Популярные фреймворки, использующие управление кешем:

  • Magento 2
  • Добавьте свой собственный!

Синопсис

http {
    server {
        location /static/ {
            immutable on;
        }
    }
}

это приведет к следующим HTTP заголовкам:

...
Cache-Control: public,max-age=31536000,stale-while-revalidate=31536000,stale-if-error=31536000,immutable
Expires: Thu, 31 Dec 2037 23:55:55 GMT 
...

Как это отличается от expires max;:

  • Устанавливает атрибут immutable, например Cache-Control: public,max-age=31536000,immutable для улучшенного кеширования. Это 1 год, а не 10 лет, посмотрите, почему ниже.
  • Отправляет Expires только когда это действительно необходимо, например, когда клиент запрашивает ресурсы через HTTP/1.0
  • Устанавливает атрибут public, чтобы обеспечить возможность кеширования ресурсов публичными кешами, что обычно является желаемым.

Из-за недостаточной поддержки immutable в браузерах на базе Chromium, мы также добавляем stale-while-revalidate=31536000,stale-if-error=31536000, что помогает улучшить коэффициент попадания в кеш в крайних случаях. Использование этих директив позволяет обслуживать кешированные ответы за пределами их срока хранения, что в случае неизменяемых ресурсов является вечным.

Таким образом, в большинстве случаев immutable on; можно использовать в качестве лучшей альтернативы expires max; для реализации схемы управления кешем.

Почему 31536000 секунд (1 год?)

RFC определяет использование одного года для обозначения ответа как "никогда не истекающий":

Чтобы пометить ответ как "никогда не истекающий", сервер источника отправляет дату Expires примерно через год с момента отправки ответа. Серверы HTTP/1.1 НЕ ДОЛЖНЫ отправлять даты Expires более чем на один год вперед.

Более подробная информация в статье.

Пример: Конфигурация производства Magento 2

При условии, что ваш магазин работает в режиме производства, вы уже скомпилировали все ресурсы. Эта пример конфигурации может быть оптимизирована до:

location /static/ {
    immutable on;

    # Удалите подпись статических файлов, которая используется для обхода кеша браузера
    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        immutable off;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

При использовании вместе с ngx_security_headers его можно упростить еще больше:

security_headers on;

location /static/ {
    immutable on;

    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        immutable off;
    }
}