Оптимизация больших сайтов. ч.1
Многие говорят, что MODX не очень оптимизирован для сайтов с большим количеством ресурсов. В основном говорят о пределе в 30-50 тыс. ресурсов. Дальше начинаются тормоза. Всё это справедливо, если пользоваться только базовыми настройками и готовыми компонентами. Опытные разработчики, конечно, могут обойти все узкие места. Но они, как правило, тусуются в лагере фреймворков, в MODX их мало. Это же справедливо и для других CMS. У них другой сегмент рынка. Это готовый инструмент — устанавливай и наполняй контентом. Но всему есть предел.
Итак, поговорим о том, что делать, если ваш сайт активно развивается и перешагнул границу в 100 тысяч ресурсов. При посещаемости в несколько тысяч уников в день вопрос об оптимизации встаёт особо остро. Любой разработчик высоконагруженных сайтов скажет, что первое, на что делают акцент, это кэш и очереди. Начнём с кэша. Для начала я советую ознакомиться с возможностями кэширования, которые MODX предлагает из коробки.
Настройки кэширования
В первую очередь для таких сайтов советуют отключать карту псевдонимов (алиасов). За это отвечает системная настройка cache_alias_map
, которая связывает id ресурса и с его uri. Эта карта используется при парсинге ссылок типа [[~7]]
и при запросе страницы для поиска ресурса по указанному в адресной строки URI. Если её отключить, то MODX будет делать запрос в БД, чтобы по URI найти id ресурса. Чтобы этого избежать, просто сразу указывайте URI нужного ресурса вместо таких тегов.
Что нам даст её отключение? Экономию ресурсов. Данная карта сохраняется в кэше контекста и очень сильно влияет на размер файла — сколько ресурсов, столько и строчек в файле. И все эти данные загружаются в память.
Но эта карта не одна. MODX также строит карту ресурсов, которая представляет собой одноуровневый массив ресурсов (ключи массива) и их прямых потомков (массив id чилдренов). Она используется в методах modX::getParentIds()
и modX::getChildIds()
. Эта карта также сильно раздувает кэш контекста, но в отличие от карты алиасов для неё не задумали возможности отключения. Причина скорее всего в том, что она более важная, чем карта алиасов. Мы добавим эту возможность.
Даже в phpDoc кэш-менеджера стоит пометка сделать рефакторинг метода генерации кэша контекста для уменьшения памяти и размера файла.
Из моего опыта
У сайта, который я оптимизировал, количество ресурсов около 160 тысяч. Размер таблицы 640 МБ. Даже с отключённой картой алиасов файл кэша контекста занимал чуть более 160 тысяч строк и весил более 5 МБ. Генерация кэша занимала от 0.3 до 0.5 секунд. После оптимизации в нём всего 11 тыс. строк и весит он не более 30 КБ.
Для управления картой ресурсов нам придётся расширить стандартный кэш-менеджер оптимизированным вариантом. На 214 строчке мы видим, что запрос ограничен только первым уровнем ресурсов
$sql .= "WHERE `r`.`deleted` = 0 and `r`.`parent` = 0 ";
Вы можете указать своё условие, если нужно. Кроме того, теперь вы можете управлять картой ресурсов. Для этого нужно создать системную настройку cache_resource_map
в разделе «Кэширование» с типом «Да/Нет».
Разместить этот класс нужно в системной папке core/model/modx/
. MODX подгрузит его автоматически. Следующим шагом нужно указать MODX, чтобы он использовал именно его. Для этого предназначена системная настройка modCacheManager.class
. Но так как кэш-менеджер подключается при инициализации объекта $modx
ещё до события OnMODXInit, то подключить его в плагине не получится. Поэтому используем другой механизм — через файл настроек core/config/config.inc.php
.

Теперь вы можете управлять кэшем контекста по своему желанию.
Внимание!
Ограничение списка ресурсов в карте ресурсов повлияет на функционал, использующий методы modX::getParentIds()
и modX::getChildIds()
. Это может проявиться в следующих местах:
- 2 вида TV — автотег и список ресурсов. Выход простой — добавить нужные ресурсы-родители в запрос для формирования карты ресурсов или заменить другим решением.
- Проверка на перемещение родителя в дочерний элемент при сохранении ресурса. Но это только при работе в форме редактирования ресурса или в режиме API, в дереве ресурсов этого сделать нельзя.
- В интерфейсе удалённых ресурсов. Но опять же с оговорками. Если вы удаляете ресурс в дереве, то автоматически удалятся и все дочерние ресурсы (кстати, очень неоптимальным путём — запросом в БД для каждого ресурса вместо использования карты ресурсов). А если удалите его (пометите удалённым) с помощью API, то в дереве удалённым отобразится только этот ресурс, а дочерние ресурсы останутся неудалёнными. Но в интерфейсе корзины они отобразятся все. Это выглядит немного странно.
- Компоненты, использующие данные методы. И первый в списке pdoTools. О нём мы поговорим подробнее чуть позже.
Остальные системные настройки такие

Хочу обратить внимание, что отключено кэширование скриптов, так как профита в этом никакого нет, только лишние файлы создаются. А ещё отключена настройка «Очищать кэш по-умолчанию». Если её не отключить, то при сохранении ресурса будут удалены кэш ресурсов, кэш контекста, кэш базы данных и кэш автопубликаций. Если 2 последних кэша редко кто использует (автопубликации ещё бывает, а кэш БД крайне редко), то очищать кэш всех ресурсов крайне вредно с точки зрения оптимизации. По кэшу контекста есть важная деталь — при сохранении ресурса кэш контекста перегенерируется 2 раза. Поэтому отключение этой настройки позволяет исключить одну перегенерацию. + 10 к уровню оптимизации :). Представьте, что у вас десятки тысяч ресурсов и кэш-менеджер вынужден 2 раза посылать запросы по ресурсам, плагинам, событиям, правам доступа, а потом разбирать их, чтобы создать кэш.
Для информации!
Когда MODX очищает кэш системных настроек (например, при редактировании настройки), кэш контекста или кэш автопубликаций, то, в отличие от других кэшей, они сразу же пересоздаются. Напомню также, что при сохранении любого элемента сбрасывается кэш всего сайта.
Заключение
С настройками кэширования разобрались. В следующей части рассмотрим подход к кэшированию ресурса.
Вы должны авторизоваться, чтобы оставлять комментарии.
Комментарии ()