Шпаргалка: кеширование картинок, CSS и JS в NGINX

    Заметка для тех, кто не специалист в NGINX, а проблему нужно решить быстро.

    Допустим, у вас на сервере стоит NGINX и вы хотите, чтобы вся статика кешировалась у клиента. В конфиге хоста NGINX пропишите это:

    server {
    listen 80;
    server_name mysite.com;
    ...
    # Задаем правила обработки статического контента (типов файлов можно поставить и больше)
    location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|pdf|ppt|txt|bmp|rtf|js)$ {
    root /path/to/document/root/; # Путь к корню вашего сайта
    access_log off; # не пишем логи
    expires 3d; # кешируем у клиента на 3 дня
    }
    }

    Проверить можно в FireBug во вкладке NET: обновите страницу 2 раза и посмотрите код ответа. Если 200 ОК, то не работает. Если 304 Not Modified, то работает.

    Неплохо ускоряет работу сайта.
    Студия Михаила Кечинова
    26.46
    Company
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 30

      +3
      Вставлю свои пять копеек: если вы используете Drupal с модулем ImageCache (а если вы используете первое, то второе вам по-любому пригодится, если на вашем сайте встречаются хоть какие-то картинки, которые надо как-то обрабатывать, например, укладывая в галереи или выводя в виде миниатюр), то перед указанным обработчиком, надо вставить ещё один, иначе картинки генериться не будут.

      Примерный конфиг тут: kostin.mmm-tasty.ru/entries/1124125
      • UFO just landed and posted this here
          0
          только вот с
          expires 100d;
          вы переборщили малость.
            0
            Это ведь просто шпаргалка-пример. Дальше каждый уже настраивает себе индивидуально. Тот же «access_log off;» никак не влияет на кеширование. Лишь снимает нагрузку с сервера.
              +1
              дык и не про кеширование ваша шпаргалка, а просто про перенос статики на фронтэнд, т.е. на отдачу ее nginx-ом напрямую.
                0
                Не совсем. Если быть точнее, то про ту часть, которая в шпаргалке подчеркнута. Исходим из того, что то, что не подчеркнуто, уже было в конфиге.

                Ну, про 100 дней вы, конечно, правы. В действительности достаточно и 7 дней. Может быть и меньше (зависит от того, как как часто меняется статический контент).
                  0
                  «Неплохо ускоряет работу сайта» как раз те опции, которые, по-вашему, уже были в конфиге, т.е. перенос статики на плечи энджи. А вот принудительная передача клиентам хедера «expires» — весьма спорный момент в плане «ускорения». Только если у вас мегабайтные картинки десятками по сайту разбросаны и канал у сервера худенький.
                  Выключать лог в контексте данной «шпаргалки» также неуместно. Это самостоятельное действие, никак не связанное с кешированием, отдачей статики, заголовками http и т.п. Диск разгрузит, да. Но потеряете статистику. Кто-то может и бездумно скопипастить вашу «шпаргалку», а потом вопли «где логи?!!, почему я логотип изменил, а он всё тот же??»
                    0
                    Про мегабайтные картинки. Бывают еще картинки по 200К. Например фоновые. И не очень быстрый интернет-канал на работе у людей. Тут кеширование тоже помогает.

                    И я не говорю о том, что вынос статики в nginx НЕ ускоряет работу клиента с сайтом. Я говорю о том, что кеширование картинок дополнительно ускоряет работу.

                    Шпаргалка, она на то и шпаргалка, что короткая и не копирует документацию системы, а просто показывает визуально — что сделать и где. Или не так?

                    Скажите, о чем мы сейчас спорим? О том, что «шпаргалка» написана неправильно?
                      0
                      никто и не спорит ни о чём. Шпаргалка ваша просто получилась совсем неюзабельная, а потому в большинстве случаев неприменимая. Следовательно — бесполезная. Проще уж открыть таки доку на русском языке и сделать всё с пониманием процесса. От таких шпаргалок больше вреда, чем пользы.
                        +1
                        Окэй, поставил 3 дня. И добавил 2 комментария рядом с директивами.
                          +1
                          вот теперь это — шпаргалка.
                    • UFO just landed and posted this here
                        0
                        вот этого как раз и нет в данном случае. Пусть уж автор хоть комменты расставит к опциям конфига, тогда будет польза.
            • UFO just landed and posted this here
                –3
                Как-то раз приходилось делать так, как у вас описано в последнем варианте, но мы просто добавляли к имени вес файла. Что-то типа:

                <link rel="stylesheet" type="text/css" media="screen" href="css/all.v<?=filesize('css/all.css')?>.css"/>
                


                • UFO just landed and posted this here
                    0
                    тогда уж filemtime. Мы такой вариант для некоторых картинок используем где мгновенное обновление важно
                      0
                      В tornado очень правильно сделано «агрессивное» кеширование статики. там пример конфигурации nginx есть: www.tornadoweb.org/documentation#static-files-and-aggressive-file-caching
                        +1
                        почему бы просто не инкрементировать версию CSS/JS файла через доп параметр типа

                        <link rel="stylesheet" type="text/css" media="screen" href="css/all.css?100500"/>

                          0
                          Инкрементировать придется вручную. А в указанном выше примере вручную менять значение размера файла не нужно.
                        +3
                        Очень просто: styles.css?v=1.1

                        Где v — версия файла или даже пакета файлов.
                        • UFO just landed and posted this here
                            0
                            > Кстати а вы не знаете, будет ли такой запрос всегда нормально кешироваться?

                            Знаю, будет всегда.

                            > Я же говорил о том, что хочется изящного и безгеморойного решения.

                            Версионировать пакеты и выкладывать на боевой сервер только протестированный код с инкрементом циферки с номером версии — очень хорошее, изящное и безгеморройное решение.
                          0
                          Как-то так это в nginx пишется:
                             rewrite ^(.*)\.[0-9]*\.css$ $1.css last;
                             rewrite ^(.*)\.[0-9]*\.js$ $1.js last;
                          

                          А номерок не забывать обновлять… Как пару раз наткнётесь на разлетевшийся макет, так и научитесь не забывать :-)
                          +1
                          А нужно делать так, что бы браузер вообще не посылал запрос, на который получит «304 Not Modified»:
                          add_header Cache-Control public,max-age=259200

                          Кроме того регулярное выражение в location — это медленно, лучше просто иметь директорию или даже домен для статики. и тогда:
                          location /media/ {
                              ...
                          }

                          А выключать логи для статики — правильно, я забыл про это.
                            0
                            Тут бы еще надо упомянуть плагин YSlow для FireBug, который покажет все незакэшированные файлы, несжатый js и много другой полезной информации, а также выставит странице общую оценку.

                            Про логи здорово, спасибо за наводку, как-то не думал об этом
                              0
                              Или Page Speed от Google. он тоже хорошо показывает, что и как можно оптимизировать (закешировать, минифицировать, сжать...)
                              –4
                              Не мучайтесь: webo.in
                                0
                                > expires 3d; # кешируем у клиента на 3 дня

                                > Проверить можно в FireBug во вкладке NET:
                                > обновите страницу 2 раза и посмотрите код ответа.
                                > Если 200 ОК, то не работает. Если 304 Not Modified, то работает.

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

                                304 Not Modified получается когда принудительно обновляем страницу или когда протухает время кеширования контента. Тогда браузер отправляет HTTP запрос серверу с заголовком If-Modified-Since (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). Сервер на этот запрос высылает контент, если файл был модифицирован, иначе говорит «304 Not Modified»…

                                Expires не имеет смысла выставлять на время, бОльшее 1 часа потому что:
                                1) Основная масса пользователей проводит на сайте время, меньшее 1 часа.
                                2) При протухании контента браузер отправит на сервер запрос с If-Modified-Since и сервер не будет заново закачивать контен в браузер, а просто отдаст короткий ответ 304 Not Modified

                                Осмелюсь порекомендовать устанавливать

                                expires 10m;
                                  0
                                  Кину свои пять копеек, вот как у меня:
                                  #Make nginx serve static content
                                  location ~*
                                  ^.+\.(html|htm|css|xml|rss|gif|jpeg|jpg|js|atom|mml|txt|jad|wml|htc|png|tif|tiff|wbmp|ico|jng|bmp|jar|war|ear|hqx|doc|pdf|ps|eps|ai|rtf|xls|ppt|wmlc|xhtml|cco|jardiff|jnlp|run|pl|pm|prc|pdb|rar|rpm|sea|swf|sit|tcl|tk|der|pem|crt|xpi|zip|bin|exe|dll|deb|dmg|eot|iso|img|msi|msp|msm|mid|midi|kar|mp3|ra|3gpp|3gp|mpeg|mpg|mov|flv|mng|asx|asf|wmv|avi|rar)$
                                  {
                                  root /var/www/DevVmPhp;

                                  #Try to handle unavailable files with Apache
                                  error_page 400 401 402 403 404 405 406 = @fallback;
                                  }

                                  location @fallback {
                                  proxy_pass 127.0.0.1:80;
                                  expires -1;
                                  }

                                  Т.е. если файлика в статичном контенте нету, то запросить и отдать от сервера, а не просто возвращать 404

                                  Only users with full accounts can post comments. Log in, please.