- Что такое кеширование
- Зачем использовать кеширование на сайте
- Недостатки и отрицательный эффект от кеширования сайта
- Как настроить кеширование у себя на сайте
- Кеширование на стороне сервера
- Кеширование с помощью NGINX
- Кеширование с помощью htaccess (Apache)
- Кеширование с помощью Memcached
- Кеширование с помощью акселератора php
- Кеширование на стороне сайта
- Кеширование на стороне браузера (клиента), заголовки кеширования
- Expires
- Cache-Control: max-age;
- Last-Modified и ETag
- Включить GZIP сжатие для статичных файлов
Что такое кеширование
Кеширование (caching) — это технология или процесс создания копии данных на быстродоступных носителях информации (кеш, cash). Проще говоря и применяя к реалиям сайтостроения, это может быть создание статической html-копии страницы или её части, которая генерируется с помощью PHP-скриптов (или иных других, как-то Perl, ASP.net), смотря на каком языке написан CMS сайта) и сохраняется на диске, в оперативной памяти или даже частично в браузере (рассмотрим подробнее ниже). Когда произойдёт запрос страницы от клиента (браузера), вместо того, чтобы заново собирать её скриптами, браузер получит её готовую копию, что намного экономнее по затратам ресурсов хостинга, и быстрее, так как передать готовую страницу занимает меньше времени (порой значительно меньше), чем её создание заново.
Зачем использовать кеширование на сайте
- Для снижения нагрузки на хостинг
- Для быстрой отдачи содержимого сайта браузеру
Оба аргумента, думаю, в комментариях не нуждаются.
Недостатки и отрицательный эффект от кеширования сайта
Как ни странно, у кеширования сайта есть и свои минусы. В первую очередь это касается сайтов, содержание которых динамично изменяется при взаимодействии с ним. Зачастую, это сайты, которые выдают содержимое или его часть с помощью AJAX. В общем-то, кеширование AJAX тоже возможно и даже нужно, но это тема для отдельного разговора и не касается традиционно используемых технологий, о которых пойдёт речь далее.
Также, проблемы могут возникнуть у зарегистрированных пользователей, для которых постоянный кеш может стать проблемой при взаимодействии с элементами сайта. Тут, как правило, кеш отключается, либо используется объектное кеширование отдельных элементов сайта: виджетов, меню и тому подобных.
Как настроить кеширование у себя на сайте
Для начала, надо разобраться какие технологии традиционно используются для кеширования содержимого сайтов.
Все возможные способы можно разделить на 3 группы
- Кеширование на стороне сервера
- Кеширование на стороне сайта
- Кеширование на стороне браузера (клиента), заголовки кеширования
Кеширование на стороне сервера
- Кеширование с помощью NGINX
- Кеширование с помощью Apache
- Кеширование с помощью Memcached
- Кеширование с помощью акселератора php
Кеширование с помощью NGINX
На хостинге используется NGINX. Как правило, в качестве вебсервера работает связка NGINX + Apache. На мой взгляд, это наиболее удачный вариант для большинства сайтов и веб-проектов. NGINX используется как принимающий основную нагрузку кеширующий сервер, работающий во фротнэнде, Apache же работает с динамикой, собирая из скриптов html-страницу выдачи. Задачей NGINX является проверить, находится ли в кеше копия требуемой страницы (при работе в связке с Varnish или Memcached) либо её статичных элементов (стилей, скриптов, изображений, аудио- и видеофайлов и других медиа), их актуальность, и, если всё в порядке, отдать результат браузеру.
Как можно настроить кеширование NGINX и WP Super Cache
Если вы не используете NGINX, категорически рекомендую использовать его, он серьёзно повышает производительность сервера.
Кеширование с помощью htaccess (Apache)
Если у вас есть доступ только к .htaccess
, и рабочий сервер только Apache, то вы можете использовать такие приёмы, как сжатие gzip и выставление HTTP заголовков Expires
, чтобы использовать браузерный кеш.
Включаем сжатие gzip для соответствующих MIME-типов файлов
<IfModule mod_deflate.c> <IfModule mod_filter.c> AddOutputFilterByType DEFLATE text/plain text/html AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript AddOutputFilterByType DEFLATE text/xml application/xml application/xhtml+xml application/rss+xml AddOutputFilterByType DEFLATE application/json AddOutputFilterByType DEFLATE application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon </ifModule> </IfModule>
Включаем заголовки Expires для статичных файлов сроком на 1 год (365 дней)
<IfModule mod_expires.c> <Filesmatch "\.(jpg|jpeg|png|gif|js|css|swf|ico|woff|mp3)$"> ExpiresActive on ExpiresDefault "access plus 365 days" </Filesmatch> </IfModule>
Кеширование с помощью Memcached
Суть работы Memcached — сохранять данные в оперативную память и отдавать браузеру оттуда уже скомпилированную готовую страницу или её фрагменты. В принципе, туда можно сохранять всё, что угодно: результат «тяжёлых» запросов к базе данных, временно необходимые объекты и тому подобное. Так выходит намного быстрее, нежели чем читать даже статические html-файлы c hdd-диска, не говоря уже про постоянную генерацию страниц при каждом запросе к ним. Как установить и настроить Memcached
Кеширование с помощью акселератора php
Если движок сайта написан на PHP, то при каждой загрузке любой страницы сайта происходит исполнение скриптов php: интерпретатор кода читает скрипты, написанные программистом, генерирует из них байткод, понятный машине, исполняет его и выдаёт результат. Акселератор PHP позволяет исключить постоянную генерацию байткода, кешируя скомпилированный код в памяти или на диске, тем самым увеличивая производительность и уменьшая время, затрачиваемое на исполнение PHP. Из поддерживаемых на сегодня акселераторов существует:
- Windows Cache Extension for PHP
- XCache
- Zend OPcache
В PHP версии
5.5
и выше уже встроен акселератор Zend OPcache, поэтому чтобы включить акселератор, вам достаточно просто обновить версию PHP
Кеширование на стороне сайта
Как правило, тут подразумевается возможность CMS сайта создавать статические html-копии страниц. Такой возможностью обладают большинство популярных движков и фреймворков. Лично я работал со Smarty, WordPress, поэтому могу заверить, что они отлично справляются со своей работой. В оригинальном WordPress из коробки нет кеширующих возможностей, которые необходимы любому малость нагруженному проекту, зато есть множество популярных плагинов для кеширования:
- WP Super Cache, который как раз и занимается генерацией статических страниц сайта;
- Hyper Cache, который по сути работает так же, как и предыдущий плагин;
- DB Cache. Суть работы — кеширование запросов к базе данных. Тоже очень полезная функция. Можно использовать в связке с двумя предыдущими плагинами;
- W3 Total Cache. Оставил его на десерт, это мой любимый плагин в WordPress. С ним сайт преображается, превращаясь из неповоротливого автобуса в гоночный болид. Его огромным преимуществом является огромный набор возможностей, как то несколько вариантов кеширования (статика, акселераторы, Memcached, запросы к базе данных, объектное и страничное кеширование), конкатенация и минификация кода (объединение и сжатие файлов CSS, Javascript, сжатие HTML за счёт удаления пробелов), использование CDN и многое другое.
Что тут скажешь — используйте правильные CMS, и качественное кеширование будет доступно практически из коробки.
Кеширование на стороне браузера (клиента), заголовки кеширования
Кеширование в браузере возможно потому, что любой уважающий себя браузер это позволяет и поощряет. Возможно это благодаря HTTP заголовкам, которые сервер отдаёт клиенту, а именно:
- Expires;
- Cache-Control: max-age;
- Last-Modified;
- ETag.
Благодаря им пользователи, которые неоднократно заходят на сайт, тратят крайне мало времени на загрузку страниц. Заголовки кеширования должны применяться ко всем кешируемым статическим ресурсам: файлы шаблона, картинок, файлы javascript и css, если есть, PDF, аудио и видео, и так далее.
Рекомендуется выставлять заголовки так, чтобы статика хранилась не менее недели и не более года, лучше всего год.
Expires
Заголовок Expires отвечает за то, как долго кеш является актуальным, и браузер может использовать кешированные ресурсы, не запрашивая у сервера их новую версию. Является сильным и крайне желательным к использованию, так как действует в обязательном порядке. В заголовке рекомендуется указывать срок от недели до года. Больше года лучше не указывать, это является нарушением правил RFC.
Например, чтобы настроить Expires в NGINX для всех статических файлов на год (365 дней), в конфигурационном файле NGINX должен присутствовать код
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; }
Чтобы настроить Expires в Apache для всех статических файлов на год (365 дней), в конфигурационном файле Apache, либо в .htaccess нужно прописать
<IfModule mod_expires.c> <Filesmatch "\.(jpg|jpeg|png|gif|js|css|swf|ico|woff|mp3)$"> ExpiresActive on ExpiresDefault "access plus 365 days" </Filesmatch> </IfModule>
Cache-Control: max-age;
Cache-Control: max-age отвечает за то же самое.
Более предпочтительно использование Expires, нежели Cache-Control ввиду большей распространённости. Однако, если Expires и Cache-Control будут присутствовать в заголовках одновременно, то приоритет будет отдан Cache-Control.
В NGINX Cache-Control включается так же, как и Expires, директивой
expires: 365d;
Пример настройки Cache-Control в Apache при включённом кеширующем модуле mod_expires.
<FilesMatch "\.(js|css|svg|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip)$"> Header set Cache-Control "max-age=2592000, must-revalidate" </FilesMatch>В данном примере, кеширующий заголовок включает кеш всех файлов, имеющих вышеперечисленные расширения сроком на 6 месяцев (2592000 секунд).
Last-Modified и ETag
Эти заголовки работают по принципу цифровых отпечатков. Это означает, что для каждого адреса URL в кеше будет устанавливаться свой уникальный id. Last-Modified создаёт его на основе даты последнего изменения. Заголовок ETag использует любой уникальный идентификатор ресурса (чаще всего это версия файла или хеш контента). Last-Modified – «слабый» заголовок, так как браузер применяет эвристические алгоритмы, чтобы определить, запрашивать ли элемент из кеша.
В NGINX для статичных файлов ETag и Last-Modified включены по умолчанию. Для динамических страниц их либо лучше не указывать, либо это должен делать скрипт, генерирующий страницу, либо, что лучше всего, использовать правильно настроенный кеш, тогда NGINX сам позаботится о заголовках. Например, для WordPress, вы можете воспользоваться WP Super Cache.
Эти заголовки позволяют браузеру эффективно обновлять кешированные ресурсы, отправляя запросы GET каждый раз, когда пользователь явным образом перезагружает страницу. Условные запросы GET не возвращают полный ответ, если ресурс не изменился на сервере, и таким образом обеспечивают меньшую задержку, чем полные запросы, тем самым уменьшая нагрузку на хостинг и уменьшая время ответа.
Одновременное использование Expires и Cache-Control: max-age избыточно, так же, как избыточно одновременное использование Last-Modified и ETag. Используйте в связке Expires + ETag либо Expires + Last-Modified.
Кстати, есть статья о том, как настроить Last-modified в WordPress
Включить GZIP сжатие для статичных файлов
Конечно, сжатие GZIP не относится к кешированию как таковому напрямую, однако, весьма экономит трафик и увеличивает скорость загрузки страниц.
- Как включить GZIP для статики в NGINX
-
server { .... gzip on; gzip_disable "msie6"; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; }
- Как включить GZIP для статики в .htaccess (Apache)
-
Чтобы включить сжатие gzip в .htaccess, нужно в начало файла вставить следующий код:
<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript </IfModule>
Свежие комментарии