
NGCMS — достаточно лёгкая CMS, однако со временем даже хорошо настроенный сайт может начать работать медленнее. Большое количество новостей, изображений, активных плагинов, запросов к базе данных и неоптимизированных шаблонов постепенно увеличивают нагрузку на сервер.
В этой статье разберём, как выполнить комплексную оптимизацию скорости NGCMS: от настроек PHP и MySQL до кеширования, шаблонов Twig, изображений, CSS, JavaScript и работы плагинов.
Скорость работы сайта зависит не только от самой CMS. На производительность одновременно влияют несколько компонентов:
Поэтому простое увеличение оперативной памяти сервера далеко не всегда решает проблему. Сначала необходимо определить, какая именно часть сайта является узким местом.
Для современной версии NGCMS желательно использовать актуальную поддерживаемую версию PHP. Старые версии PHP не только работают медленнее, но и могут содержать устаревшие механизмы, которые мешают дальнейшей оптимизации.
Проверить установленную версию PHP можно командой:
php -v
Например:
PHP 8.4.x (cli)
Однако важно помнить, что версия PHP в командной строке и версия PHP, используемая веб-сервером, могут отличаться.
Проверить PHP, который используется сайтом, можно через небольшой файл:
<?php
phpinfo();
После проверки файл phpinfo.php необходимо удалить с сервера, поскольку открытая информация о конфигурации PHP не должна постоянно находиться в публичном доступе.
Одним из самых эффективных способов ускорения PHP-приложений является OPcache.
Без OPcache PHP при каждом запросе должен читать PHP-файлы и компилировать их в байткод. При включённом OPcache уже скомпилированный код хранится в оперативной памяти.
Проверить наличие OPcache можно командой:
php -m | grep -i opcache
Или проверить параметр:
php -i | grep opcache.enable
В конфигурации PHP обычно должны присутствовать параметры, аналогичные следующим:
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
Конкретные значения необходимо подбирать с учётом размера проекта и доступной оперативной памяти.
Для рабочего сайта можно использовать более редкую проверку изменения файлов:
opcache.validate_timestamps=1
opcache.revalidate_freq=5
При разработке NGCMS лучше оставить более частую проверку, чтобы изменения PHP-файлов сразу применялись.
Если сайт работает через PHP-FPM, необходимо правильно подобрать количество PHP-процессов.
Слишком маленькое значение приводит к появлению очереди запросов. Слишком большое количество процессов, наоборот, может полностью занять оперативную память сервера.
Основные параметры PHP-FPM:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
Это только пример. Для небольшого сайта количество процессов может быть значительно меньше, а для крупного проекта — больше.
Главное правило: не увеличивайте pm.max_children вслепую. Каждый PHP-процесс потребляет оперативную память.
Если на сервере мало оперативной памяти, большое количество PHP-процессов может привести к использованию swap и резкому падению производительности.
Проверить память можно командой:
free -h
А текущие PHP-процессы:
ps aux | grep php
Если сервер начинает активно использовать swap, сначала необходимо разобраться с потреблением памяти, а уже потом увеличивать количество PHP-FPM workers.
На динамическом сайте база данных является одним из наиболее важных элементов производительности.
NGCMS постоянно обращается к базе данных для получения новостей, категорий, комментариев, пользователей, тегов и других данных.
Проверить версию MySQL или MariaDB:
mysql --version
Для диагностики медленных запросов можно использовать slow query log.
Идея проста: вместо того чтобы пытаться оптимизировать всё подряд, сначала находим запросы, которые реально занимают много времени.
Одна из распространённых причин замедления NGCMS — большое количество активных плагинов.
Сам факт наличия большого количества файлов плагинов не обязательно является проблемой. Гораздо важнее то, что плагины выполняют при каждом запросе страницы.
Особенно внимательно следует относиться к плагинам, которые:
Если какой-либо функционал используется редко, не всегда имеет смысл выполнять его код на каждом запросе.
Если после установки нового плагина сайт стал заметно медленнее, наиболее простой способ поиска проблемы — временно отключить подозрительный плагин и сравнить время генерации страницы.
Это особенно полезно при разработке собственных расширений NGCMS.
Например, если плагин выводит список последних комментариев, нет смысла каждый раз получать из базы сотни записей, если пользователю необходимо показать только пять.
Лучше ограничить SQL-запрос:
SELECT ...
FROM ...
ORDER BY ...
LIMIT 5
Чем меньше данных передаётся из базы в PHP, тем меньше памяти и процессорного времени требуется приложению.
Одна из типичных ошибок начинающих разработчиков — получение всех записей из таблицы с последующей обработкой массива в PHP.
Например, плохой вариант:
SELECT * FROM news
Если в базе находится 50 000 новостей, PHP потенциально получает огромный объём данных, хотя на странице может потребоваться всего 10 записей.
Гораздо правильнее:
SELECT ...
FROM news
ORDER BY id DESC
LIMIT 10
Фильтрацию и сортировку по возможности следует выполнять непосредственно на стороне базы данных.
Если таблицы NGCMS содержат большое количество записей, наличие правильных индексов становится особенно важным.
Например, если запрос часто выполняется по определённому полю:
SELECT *
FROM news
WHERE category = 5
то соответствующий индекс может существенно ускорить поиск.
Проверить структуру таблицы можно через:
SHOW INDEX FROM news;
Однако добавлять индексы на все поля подряд тоже не следует. Каждый индекс занимает место и увеличивает стоимость операций INSERT и UPDATE.
Если один и тот же результат приходится формировать много раз, разумнее один раз получить его и сохранить.
Именно для этого используется кеширование.
Кешировать можно:
Особенно полезно кеширование для блоков, которые изменяются редко.
Например, список популярных материалов не обязательно пересчитывать при каждом открытии страницы.
Кеширование должно учитывать актуальность данных.
Если пользователь опубликовал новую новость, а кеш страницы хранится сутки, посетитель может некоторое время видеть старую версию страницы.
Поэтому для разных данных можно использовать разное время жизни кеша:
При использовании Twig желательно избегать лишних вычислений непосредственно в шаблоне.
Шаблон должен в первую очередь отвечать за отображение данных, а не выполнять сложную бизнес-логику.
Если один и тот же результат можно получить один раз в PHP и передать в Twig, это обычно предпочтительнее многократного выполнения одинаковых операций внутри шаблона.
Например, не стоит несколько раз получать одни и те же данные внутри цикла, если их можно подготовить заранее.
Особенно опасна конструкция, когда внутри цикла выполняется SQL-запрос.
Например:
получить 100 новостей
для каждой новости:
выполнить отдельный SQL-запрос
В результате вместо одного запроса можно получить 101 запрос к базе данных.
Такую ситуацию называют проблемой N+1 запросов.
Правильнее заранее получить необходимые данные одним запросом или использовать JOIN.
На современных сайтах изображения часто являются самым большим источником передаваемых данных.
Даже идеально оптимизированный PHP не сделает страницу быстрой, если посетителю приходится загружать несколько фотографий размером по 5–10 МБ.
Перед публикацией изображения желательно:
Например, если картинка отображается шириной 800 пикселей, нет большого смысла отправлять браузеру оригинал шириной 6000 пикселей.
Для изображений, находящихся ниже первого экрана, можно использовать ленивую загрузку:
<img src="/uploads/image.webp"
loading="lazy"
alt="Описание изображения">
Браузер не будет сразу загружать все изображения длинной страницы.
Это особенно заметно на страницах со множеством новостей и изображений.
Если тема NGCMS содержит большое количество CSS-файлов, браузеру приходится загружать и обрабатывать каждый из них.
Желательно:
JavaScript также может существенно влиять на скорость загрузки страницы.
Если скрипт не требуется для построения HTML, его можно загружать с использованием:
<script src="/js/script.js" defer></script>
Аналогично CSS и JavaScript желательно очищать от библиотек и функций, которые больше не используются.
Иногда плагину требуется всего одна небольшая функция, но ради неё подключается большая JavaScript-библиотека.
Если аналогичную операцию можно выполнить обычным JavaScript без сторонней библиотеки, это может уменьшить размер страницы и количество запросов.
Для современных браузеров многие операции уже доступны непосредственно через стандартный JavaScript.
Передаваемые HTML, CSS, JavaScript и другие текстовые файлы можно сжимать.
Современным вариантом является Brotli. Также широко используется Gzip.
Сжатие особенно эффективно для:
При правильной настройке размер передаваемых текстовых данных может уменьшиться в несколько раз.
Статические файлы NGCMS не обязательно загружать заново при каждом посещении сайта.
Для CSS, JavaScript, шрифтов и изображений можно устанавливать длительное кеширование.
Например, для файлов, имя которых меняется при изменении версии:
style.css?v=2
script.js?v=5
можно устанавливать длительный срок кеширования.
После изменения файла достаточно изменить его версию, и браузер загрузит новую копию.
Количество небольших запросов также влияет на загрузку страницы.
Стоит проверить, нет ли в шаблоне ссылок на отсутствующие файлы:
404 favicon.ico
404 image.png
404 script.js
Каждый такой запрос является лишней работой для сервера.
Даже хорошо оптимизированная NGCMS может работать медленно при неправильной настройке веб-сервера.
В зависимости от конфигурации сайта это может быть Apache или Nginx.
Важно проверить:
Иногда проблема заключается не в сервере, а в слишком большом HTML-документе.
Особенно это характерно для страниц, на которых выводятся:
Если главная страница содержит слишком много информации, имеет смысл уменьшить количество выводимых элементов и использовать пагинацию.
Например, вместо 50 полноценных новостей лучше показать 10–20 анонсов.
При этом желательно ограничивать и объём текста:
10 новостей
+
короткий анонс
+
миниатюра
Полный текст материала должен загружаться только на странице самой новости.
Старые плагины, резервные копии, тестовые файлы и временные скрипты часто остаются на сервере после завершения разработки.
Особенно опасно оставлять доступными тестовые PHP-файлы:
test.php
info.php
debug.php
old.php
backup.php
Они не только создают потенциальные проблемы безопасности, но и могут выполнять ненужные операции.
Файлы вроде:
site-backup.zip
database.sql
ngcms-old.tar.gz
не должны находиться в каталоге, доступном из интернета.
Помимо безопасности, такие файлы могут занимать значительный объём дискового пространства.
Оптимизацию нельзя выполнять только «на глаз».
После каждого существенного изменения желательно сравнивать показатели до и после.
Можно проверить:
Особое внимание стоит уделять TTFB — времени от отправки запроса до получения первых данных от сервера.
Если TTFB высокий, проблему обычно необходимо искать на стороне сервера, PHP, базы данных или приложения.
Не стоит одновременно менять десятки настроек.
Лучше использовать следующий порядок:
Так можно точно определить, какое изменение действительно дало результат.
Для обычного сайта NGCMS можно начать со следующей схемы:
NGCMS
│
├── PHP 8.x
│ └── OPcache
│
├── PHP-FPM
│ └── оптимальное количество workers
│
├── MySQL / MariaDB
│ ├── индексы
│ └── контроль медленных запросов
│
├── NGCMS
│ ├── минимум ненужных плагинов
│ ├── кеширование
│ └── оптимизированные Twig-шаблоны
│
├── Изображения
│ ├── WebP / AVIF
│ ├── правильные размеры
│ └── lazy loading
│
└── Веб-сервер
├── HTTP/2 или HTTP/3
├── Brotli / Gzip
└── Browser Cache
Правильно выполненная оптимизация позволяет получить сразу несколько преимуществ:
Оптимизация скорости NGCMS — это не одна настройка и не установка какого-либо «ускорителя». Производительность складывается из работы PHP, базы данных, NGCMS, плагинов, Twig, веб-сервера и браузера.
На небольшом сайте наибольший эффект обычно дают OPcache, правильная работа PHP-FPM, оптимизация SQL-запросов, кеширование и уменьшение размера изображений.
На крупных проектах необходимо дополнительно анализировать базу данных, количество запросов, работу отдельных плагинов и время генерации конкретных страниц.
Главное правило производительности NGCMS можно сформулировать очень просто:
Не пытайтесь ускорять то, что ещё не измерили. Сначала найдите узкое место, затем оптимизируйте именно его.
Такой подход позволяет ускорить сайт без бессмысленного изменения десятков настроек и без увеличения мощности сервера там, где это на самом деле не требуется.