Оптимізація продуктивності MODX

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Оптимізація продуктивності MODX
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Оптимізація продуктивності MODX

MODX Revolution — гнучка CMS, але без правильної настройки кешування та конфігурації сервера вона легко упирається в TTFB 2–4 секунди навіть на простих сайтах. Причина — агресивна робота з базою даних, парсинг тегів [[*]]/[[+]] на кожен запит та відсутність вбудованого об'єктного кешу.

Де теряється час: профайлювання запитів

Перший крок — зрозуміти, що саме сповільнює. MODX логує повільні запити, якщо увімкнути в core/config/config.inc.php:

define('MODX_CONFIG_KEY', 'config');
// у System Settings:
// log_level = 4 (DEBUG)
// log_target = FILE

Більш точний інструмент — xDebug + Blackfire або просто EXPLAIN у MySQL/MariaDB для запитів, які MODX генерує при рендерингу сторінки. Типові проблеми:

  • modResource читає всі поля включаючи content навіть коли потрібен лише pagetitle
  • getResources без limit робить SELECT * по всім дочірнім ресурсам
  • сніпети без &cache=1 виконуються на кожен запит

Кешування на рівні MODX

Системний кеш зберігається в core/cache/. Для production переконайтесь, що директорія має права 755 і не монтується через tmpfs без достатнього розміру.

Оптимальні налаштування в System Settings:

Параметр Рекомендоване значення
cache_resource_handler xPDOFileCache (за замовчуванням) або Redis
cache_default_lifetime 3600–86400 залежно від частоти оновлень
cache_context_settings 1
compress_js 1
compress_css 1

Для Redis-кешу встановлюється пакет Redis (modmore або аналог) і в core/config/config.inc.php додається:

$config_options = [
    'cache_path' => MODX_CORE_PATH . 'cache/',
    'cache_default_handler' => 'xPDORedisCache',
    'cache_xpdo_handler'    => 'xPDORedisCache',
    'redis_host' => '127.0.0.1',
    'redis_port' => 6379,
    'redis_db'   => 0,
];

Після переключення на Redis TTFB знижується на 30–50% на сайтах з високим трафіком, тому що відпадають дискові операції на stat() файлів кешу.

Оптимізація сніпетів та чанків

Некешовані виклики [[!SnippetName]] — головне джерело медлительності. Аудит через пошук за шаблонами та чанками:

grep -r '\[\[!' /var/www/modx/core/elements/ | grep -v '.svn'
# або в templates через MODX manager: Elements > Templates > Search

Правила:

  • Якщо сніпет не залежить від сесії/корзини/користувача — робимо кешований [[SnippetName? &cache=1 &cacheExpires=3600]]
  • getResources, pdoResources кешуються через вбудований параметр &cache
  • FormIt та Login — завжди некешовані, виносити в окремі чанки

pdoTools замість getResources — критично для сайтів з великими каталогами. pdoTools використовує JOIN замість множественних запитів:

[[pdoResources?
  &parents=`15`
  &depth=`2`
  &limit=`20`
  &sortby=`publishedon`
  &sortdir=`DESC`
  &cache=`1`
  &cacheExpires=`1800`
]]

Настройка PHP-OPcache та конфігурація PHP

; /etc/php/8.1/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0   ; на production — вимкнути
opcache.revalidate_freq=0
opcache.fast_shutdown=1

PHP-FPM pool для MODX:

[modx]
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500
request_terminate_timeout = 30s

pm.max_requests = 500 — запобігає витокам пам'яті в довгоживучих сніпетах.

Nginx + статика + gzip

server {
    # Статика з довгим кешем
    location ~* \.(js|css|png|jpg|webp|woff2|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Запрет прямого доступу до core
    location ^~ /core/ {
        deny all;
    }

    # gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript image/svg+xml;
    gzip_min_length 1024;
    gzip_comp_level 5;
}

Індекси бази даних

MODX не додає всі потрібні індекси автоматично. Для сайтів із 10 000+ ресурсів додаємо:

-- Прискорює вибір за батьком + статусом
ALTER TABLE modx_site_content
  ADD INDEX idx_parent_published (parent, published),
  ADD INDEX idx_context_published (context_key, published);

-- Для сортування за датою
ALTER TABLE modx_site_content
  ADD INDEX idx_publishedon (publishedon);

Після додавання індексів EXPLAIN SELECT на типовому запиті getResources показує ref замість ALL.

Терміни робіт

Базова оптимізація (кеш, PHP-FPM, nginx, індекси): 2–3 дні. Переведення некешованих сніпетів на кешовані + аудит шаблонів: 3–5 днів залежно від кількості елементів. Перехід на Redis-кеш з тестуванням: 1 день додатково.