Как ускорить загрузку страницы с ценами в MODX: решение проблемы 17 секунд
Владельцы сайтов на MODX нередко сталкиваются с медленной загрузкой страниц, содержащих прайс-листы. Если у вас около 400 записей цен, а время загрузки доходит до 17 секунд - проблема кроется в избыточных вызовах сниппета getImageList. В этой статье мы разберём причины тормозов и предложим работающие способы оптимизации.
Почему страница с ценами грузится 17 секунд?
В вашем шаблоне используется тройная вложенность getImageList:
- Первый вызов получает TV-поле
price_migx_itemsс лимитом 999. - Второй вызов внутри чанка
tpl_price_migxснова вызываетgetImageListдля TVprice_migx. - Третий вызов в чанке
tpl_price_migx_include- ещё одинgetImageListс лимитом 999.
Каждый такой вызов - это отдельный SQL-запрос к базе данных. При 400 элементах система выполняет тысячи лишних операций, что и вызывает долгую загрузку. Кроме того, отсутствует кэширование результатов.
Простое решение: генерация статического HTML
Один из вариантов, который вы уже попробовали - преобразовать страницу «Цены» в статический HTML. Это даёт загрузку 1-2 секунды, но лишает гибкости редактирования. Для решения этой проблемы можно реализовать механизм «одной кнопки» в админке MODX.
Как сделать кнопку «Перегенерировать HTML»?
Создайте пользовательский процессор или плагин, который:
- При нажатии кнопки в админке запускает сборку страницы через стандартные сниппеты (с сохранением в кэш).
- Записывает готовый HTML в отдельный файл или TV-поле типа Textarea.
- Выводит на фронте именно этот статический HTML, минуя тяжёлые вызовы getImageList.
Пример реализации: используйте событие OnDocFormSave или создайте своё действие в меню «Компоненты». Для кэширования подойдёт стандартный механизм MODX - $modx->cacheManager.
Альтернативные методы ускорения без потери динамики
Если вы не хотите отказываться от динамического вывода, попробуйте следующие подходы:
Оптимизация getImageList
- Уберите лишние вложенные вызовы. В вашей структуре третий getImageList дублирует данные - достаточно одного вызова с правильным TV.
- Используйте параметр
&cache=`1`для кэширования результатов. - Уменьшите лимит с 999 до реального количества записей (например, 400).
Использование pdoTools
Сниппет pdoResources из пакета pdoTools работает быстрее, чем getImageList, и поддерживает встроенное кэширование. Пример замены:
[[pdoResources? &parents=`0` &tvPrefix=`` &includeTVs=`price_migx_items` &tpl=`tpl_price_row` &limit=`400` &cache=`1`]]Выгрузка в отдельную таблицу
Создайте кастомную таблицу в БД для хранения цен. Это позволит делать один простой запрос вместо трёх. Для интеграции используйте modDB или xPDO.
Практический пример: кэширование через файл
Вот как можно реализовать кэширование в файл вручную:
- В чанк вывода добавьте проверку: если файл кэша существует и не устарел - выводим его содержимое.
- Если файла нет - выполняем все вызовы getImageList, сохраняем результат в файл.
- При редактировании цен в админке очищайте этот файл (через плагин на событие
OnResourceSave).
Этот метод даёт скорость статики и гибкость динамики.
Выводы
Медленная загрузка страницы с ценами в MODX - следствие избыточных вызовов getImageList. Чтобы ускорить сайт, выберите один из путей:
- Статический HTML с кнопкой перегенерации - максимум скорости, удобство редактирования.
- Оптимизация getImageList - убираем дубли, включаем кэш.
- Переход на pdoTools - быстрее и современнее.
- Кастомная таблица - для крупных проектов.
Рекомендуем начать с отключения лишних вложенных вызовов и включения кэширования. Если этого недостаточно - внедрите генерацию статики через кнопку в админке. Так вы сохраните удобство управления ценами и получите загрузку за 1-2 секунды.