Кэширование статики в Nginx для ускорения сайта
Почему важно кэшировать статические файлы
Каждый раз, когда пользователь заходит на ваш сайт, его браузер запрашивает десятки статических файлов: CSS, JavaScript, изображения, шрифты и многое другое. Без правильного кэширования каждый запрос нагружает сервер, увеличивая время загрузки и расход трафика. Nginx — высокопроизводительный веб-сервер, который может кардинально улучшить ситуацию, указав браузерам кэшировать эти файлы локально и кэшируя их на стороне сервера.
В этом руководстве вы узнаете, как настроить Nginx для эффективного кэширования статики, снизив задержки и нагрузку на сервер.
Разница между кэшированием в браузере и на сервере
Здесь важны два основных типа кэширования:
- Кэширование в браузере: браузер сохраняет файлы локально на основе HTTP-заголовков, таких как
Cache-ControlиExpires. При последующих визитах файлы загружаются с диска без сетевых запросов. - Кэширование на сервере: Nginx хранит ответы в памяти или на диске и отдаёт их напрямую при повторных запросах, снижая нагрузку на бэкенд.
Оба типа критически важны для производительности. Рассмотрим оба.
Шаг 1: Настройка кэширования в браузере с помощью заголовков Expires
Самый простой способ включить кэширование в браузере — добавить директивы expires в конфигурацию Nginx. Это устанавливает заголовки Expires и Cache-Control.
Откройте файл конфигурации вашего сайта (например, /etc/nginx/sites-available/example.com) и добавьте блок location для статических файлов:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Это указывает браузеру кэшировать эти файлы на один год. Директива immutable говорит о том, что файл никогда не изменится, поэтому браузер не будет даже перепроверять его при перезагрузке.
Лучшая практика: используйте версионированные имена файлов (например, style.abc123.css), чтобы обновлять файлы без нарушения кэширования. Когда файл меняется, меняется и его имя, и браузер загружает новую версию.
Шаг 2: Включение серверного кэширования через proxy_cache
Если за Nginx работает сервер приложений (например, Node.js, Python или PHP), вы можете кэшировать статические ответы в Nginx, чтобы сократить количество запросов к бэкенду.
Сначала определите путь для кэша в блоке http файла nginx.conf:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;
Затем используйте его в блоке server:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
proxy_cache static_cache;
proxy_cache_valid 200 302 1y;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
Это кэширует успешные ответы на один год и отдаёт устаревший контент, если бэкенд недоступен. Заголовок X-Cache-Status помогает при отладке (HIT, MISS и т. д.).
Шаг 3: Оптимизация с помощью сжатия и HTTP/2
Кэширование сокращает количество запросов, но вы можете ещё больше ускорить передачу, включив сжатие gzip и HTTP/2.
Включите gzip в nginx.conf:
gzip on;
gzip_types text/css application/javascript image/svg+xml;
gzip_min_length 1000;
HTTP/2 мультиплексирует запросы и включается добавлением http2 в директиву listen:
listen 443 ssl http2;
Примечание: HTTP/2 требует HTTPS. Если вы ещё не настроили TLS, см. наше руководство о том, как работают HTTPS и TLS.
Сравнение: директивы Cache-Control
| Директива | Значение | Рекомендуется для |
|---|---|---|
public |
Ответ может кэшироваться любым кэшем | Статические файлы |
private |
Ответ предназначен для одного пользователя | Пользовательские данные |
no-cache |
Требуется перепроверка на сервере | HTML-страницы |
no-store |
Никогда не кэшировать | Конфиденциальные данные |
immutable |
Содержимое не изменится | Версионированные файлы |
Шаг 4: Тестирование и проверка
После применения изменений перезагрузите Nginx: sudo nginx -s reload. Затем проверьте с помощью curl:
curl -I https://example.com/style.css
Ищите заголовки Cache-Control и Expires. Также можно использовать DevTools браузера (вкладка Network), чтобы увидеть, отдаются ли файлы из кэша (статус 200 или 304).
Для серверного кэша следите за заголовком X-Cache-Status.
Типичные ошибки и лучшие практики
- Не кэшируйте HTML: HTML должен быть динамическим или иметь короткое время кэширования, чтобы отражать обновления.
- Используйте версионирование: добавляйте хэши к именам файлов, чтобы сбрасывать кэш при изменении содержимого.
- Устанавливайте подходящий max-age: один год безопасен для версионированных файлов.
- Следите за размером кэша: серверные кэши могут разрастаться; задавайте
max_sizeиinactive. - Рассмотрите CDN: для глобальной аудитории CDN может кэшировать файлы ближе к пользователям.
FAQ
Как узнать, кэшируются ли мои файлы?
Проверьте заголовки ответа с помощью curl -I или DevTools браузера. Ищите Cache-Control: public, max-age=31536000 и заголовки Expires. В DevTools в колонке Size для кэшированных файлов будет указано "(from disk cache)".
В чём разница между expires и Cache-Control?
expires задаёт абсолютную дату, а Cache-Control использует относительные секунды. В современных браузерах приоритет имеет Cache-Control. Директива expires в Nginx устанавливает оба заголовка для совместимости.
Можно ли кэшировать динамический контент?
Да, но с осторожностью. Используйте proxy_cache с короткими TTL и учитывайте ключи кэша на основе cookie или заголовков. Для пользовательского контента используйте private или не кэшируйте вовсе.
Ускорьте работу с TryQuickToolBox
Оптимизируя производительность сайта, вам может понадобиться сжать изображения или PDF. Попробуйте наш Image Compressor, чтобы уменьшить размер изображений без потери качества — в дополнение к вашей стратегии кэширования в Nginx.