Оптимизация сайта с помощью модуля Google PageSpeed ​​для NGINX

Модуль Google PageSpeed ngx_pagespeed (или просто pagespeed) для NGINX, предназначен для автоматической оптимизации работы сайта путём сокращения времени загрузки сайта в браузере. Все действия выполняются на лету не изменяя исходных файлов сайта и его содержимого. Для снижения нагрузки в процессе работы модуля используется собственный механизм кэширования.

Данный модуль можно установить и для Apache, обычно называется mod_pagespeed и распространяется как пакет.

Ниже список наиболее востребованных возможностей модуля, полный список фильтров смотрите на официальном сайте:

  • Оптимизация изображений, компрессия, удаление метаданных, динамическое изменение размера изображений.
  • Минимизация CSS и JavaScript кода, объединение нескольких файлов в один.
  • Оптимизация HTML кода страниц сайта.
  • Продление срока кэширования файлов.
  • Отложенные загрузка и отображение JS-скриптов.

Плюсы использования pagespeed:

Минусы использования pagespeed:

  • Существует полуофициальная рекомендация от Google устанавливать Varnish перед nginx. Это не так просто:(

Официальная документация:

Используемая операционная система CentOS Linux 7.9. Для установки модуля pagespeed нам нужно будет пересобрать веб-сервер NGINX.

Установим пакеты для сборки:

yum update
yum install gcc gcc-c++ kernel-devel
yum groupinstall 'Development Tools'
yum install gcc-c++ pcre-devel zlib-devel make unzip libuuid-devel libaio-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed gperftools-devel

Узнаем версию nginx

nginx -v
nginx version: nginx/1.20.2

В это части руководства вам нужно будет загрузить исходный пакеты. У вас есть два варианта скачать стабильный или предварительный релиз модуля. Понимаем, что у обоих версий есть проблемы. Поэтому посетите GitHub и прочитайте список текущих вопросов, чтобы понять какая версия ngx_pagespeed вам подойдёт.

На момент написания статьи, релиз кандидат pagespeed был версии v1.14.33.1-RC1, а стабильный v1.13.35.2. Список возможных версий на страннице GitHub tags и имеет вид:

Я буду использовать последнюю стабильную версию, cкачиваем ее

wget https://github.com/apache/incubator-pagespeed-ngx/archive/refs/tags/latest-stable.tar.gz

Содержимое распакуйте в папку по пути:

mkdir /root/pagespeed-ngx
tar xzvf latest-stable.tar.gz

Переходим в распакованный каталог с исходниками модуля:

cd /root/pagespeed-ngx/incubator-pagespeed-ngx-latest-stable

Смотрим в файле, по какой ссылке нужно загружать PSOL (PageSpeed Optimization Libraries). В моем случае было:

cat PSOL_BINARY_URL
https://dl.google.com/dl/page-speed/psol/1.13.35.2-$BIT_SIZE_NAME.tar.gz

$BIT_SIZE_NAME нужно заменить разрядностью операционной системы, которую можно посмотреть командой uname -m, а в реальности это будет значение x64 на любом современном сервере. Скачиваем

wget https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz

Распаковываем архив с PSOL:

tar zxvf 1.13.35.2-x64.tar.gz

Предварительная часть закончена переходим к сборке.

Узнаем установленные модули. Нас интересует все что после configure arguments.

nginx -V

Приводим к виду ниже, заменив configure arguments: на ./configure. Добавим к ним информацию о расположении исходников модуля pagespeed-ngx:

--add-module=/root/pagespeed-ngx/incubator-pagespeed-ngx-latest-stable

Получаем такой код и запускаем его

./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/root/testcookie-nginx-module/testcookie-nginx-module-master --add-module=/root/pagespeed-ngx/incubator-pagespeed-ngx-latest-stable

Если в процессе конфигурирования появятся ошибки, необходимо самостоятельно разобраться, какого модуля не хватает в системе и установить его. В консоли вы увидите строки checking for psol … found и ngx_pagespeed was configured, как на скриншоте:

После окончания конфигурирования собираем исходник:

make

Ошибка make[1] Error 4

Компиляция заканчивается ошибкой
make[1]: *** [objs/addon/src/ngx_pagespeed.o] Error 4

Гуглим и выясняем, что это возможно, операционной системе не хватает памяти во время сборки. Проверяем командой free как правильно смотреть свободное ОЗУ Linux:

free -m
              total        used        free      shared  buff/cache   available
Mem:            991         417         388         106         185         357

И мы видим, что без файла подкачки у нас свободно 357 (столбец available) из одного 1 ГБ. Маловато, значит останавливаем все службы, что можем себе позволить остановить.

Опять делаем make, но предварительно нужно удалить попытки предварительной сборки (ключ clean):

make clean
make

Ооо! Успешно! Теперь инсталлируем новособранный Nginx

make install

Проверяем сборку nginx:

nginx -V

Мы должны увидеть среди configure arguments:

--add-module=/root/pagespeed-ngx/incubator-pagespeed-ngx-latest-stable

Всё! Мы собрали и установили Nginx модулем pagespeed.

После пересборки nginx модуль pagespeed не будет включен. Сначала нужно создать папку, в которой модуль будет хранить кэш файлов сайта:

mkdir -p /var/ngx_pagespeed_cache

Передайте права на эту папку пользователю Nginx, чтобы веб-сервер имел необходимый уровень доступа.

chown -R nginx:nginx /var/ngx_pagespeed_cache

Для активации модуля открываем конфигурационный файл /etc/nginx/nginx.conf. В секцию http добавляем минимальный набор опций, которых достаточно для запуска и работы PageSpeed:

pagespeed on;  
pagespeed FileCachePath /var/ngx_pagespeed_cache;

первая строка включает pagespeed, вторая — указывает на путь каталога с кэшем. Если нам нужно будет на время отключить модуль, оставим pagespeed off;

Перезапускаем nginx:

systemctl restart nginx
Все параметры могут быть добавлены в контекст http {} файла nginx.conf, но в таком случае действие Pagespeed будет распространяться на все сайты находящиеся на сервере. Если Pagespeed нужен только для конкретного сайта, то лучше всего будет прописать настройки в контексте server {} обслуживающим нужный сайт.

После того, как мы установили и применили модуль, необходимо убедиться, что он используется при работе сайта. Можно сделать это несколькими методами.

curl -I -p IP_вашего_сервера

Вы должны увидеть следующий вывод:

curl -I -p http://localhost

HTTP/1.1 404 Not Found
Server: nginx/1.20.2
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/7.4.28
Date: Sun, 03 Apr 2022 17:49:54 GMT
X-Page-Speed: 1.13.35.2-0
Cache-Control: max-age=0, no-cache

Вы должны увидеть X-Page-Speed ​​и номер версии в выводе выше. Это означает, что вы успешно установили ngx_pagespeed на сервере.

В любом браузере, например Google Chrome, вам необходимо посмотреть заголовки при ответе и убедиться, что среди них есть X-Mod-Pagespeed. Для этого запускаем браузер и кликаем F12, чтобы вызвать панель разработчика. Переходим на любой сайт на нашем сервере. В панели разработчика переходим в Network (Сеть) - кликаем по любому загруженному элементу в списке слева - Headers (Заголовки) — если наш сервер настроен верно, мы увидим заголовок X-Page-Speed и версию модуля:

Чтобы постоянно не сжимать и переписывать файлы, тем самым нагружая сервер, PageSpeed кэширует ресурсы сохраняя их в указанном каталоге.

Вы можете изучить, официальную документация по настройка кэша Configuring Server-Side Cache for PageSpeed, а можете применить советы из этой статьи. Но помните, чтение официальной документации еще никому не мешало!

На сайтах с большим количеством посетителей и трафика, кэш может разрастись и заполнить весь диск, поскольку изначально никаких ограничений на использование диска не устанавливается.

Основные директивы для управления кэшем.

pagespeed FileCacheSizeKb - задает максимальный размер кэша в килобайтах.
pagespeed FileCacheCleanIntervalMs - задает интервал очистки кэша в миллисекундах.
pagespeed FileCacheInodeLimit - задает лимит индексных дескрипторов (inode) по достижению которого кэш будет очищен.
pagespeed FileCachePath            "/var/ngx_pagespeed_cache/";
pagespeed FileCacheSizeKb          102400;
pagespeed FileCacheCleanIntervalMs 3600000;
pagespeed FileCacheInodeLimit      500000;

Подобная конфигурация будет работать следующим образом. Процесс очистки кэша будет запускаться каждый час, согласно заданного интервала, но очищаться кэш будет не всегда. Кэш будет очищен только в том случае, если его размер превысит заданные лимиты в 102 мегабайта или в 500000 inodes.

На данный момент PageSpeed работает без дополнительных настроек (в Шаг 4 мы указали минимально необходимое количество опции для включения модуля ngx_pagespeed). Но при этом делает все что должен: изображения сжимаются, код (HTML, CSS, JS) оптимизируется и т.д. Все это связано с дефолтным уровнем конфигурации.

Переходим на страницу PageSpeed Insights и вводим адрес сайта — нажимаем Анализировать. Ждем результатов и на основе их принимаем решение для оптимальных настроек модуля pagespeed.

Для облегчения настройки PageSpeed имеет три уровня конфигурации.

  • CoreFilters - максимальный набор фильтров подходящий для работы большинства сайтов. Является уровнем по умолчанию и активируется при запуске PageSpeed без дополнительных настроек.
  • OptimizeForBandwidth - минимальный набор фильтров. В основном оптимизирует и сжимает код.
  • PassThrough - полностью отключает все фильтры.

Уровни определяются директивой pagespeed RewriteLevel.

pagespeed RewriteLevel CoreFilters;

Каждый уровень может быть изменен под себя, с помощью добавления нужных или исключения ненужных фильтров.

Директива pagespeed DisableFilters исключает фильтры из конфигурации, а pagespeed EnableFilters добавляет. Фильтры указываются через запятую, например так.

# Исключаем фильтры rewrite_images и combine_css
pagespeed DisableFilters rewrite_images,combine_css;
# Добавляем фильтры rewrite_css и rewrite_javascript
pagespeed EnableFilters rewrite_css,rewrite_javascript;

Например мы хотим использовать уровень CoreFilters, но нас не все устраивает. Нам не нужно сжимать изображения и объединять CSS файлы в один. Но зато нужно встроить стили google-шрифтов непосредственно в HTML документ.

В таком случае конфигурация будет выглядеть так.

pagespeed RewriteLevel CoreFilters;
pagespeed DisableFilters rewrite_images,combine_css;
pagespeed EnableFilters inline_google_font_css;

Чтобы полностью запретить использование определенного фильтра и исключить его из всех конфигураций используется директива pagespeed ForbidFilters. Например для полного запрета использования фильтра resize_mobile_images нужно сделать так.

pagespeed ForbidFilters resize_mobile_images;
PQ VPS сервера в 28+ странах.