В последние года в связи с заявлениями Яндекс и Google о все большем влиянии скорости сайта на ранжирование в поиске, нам приходится регулярно заниматься оптимизацией скорости шаблона.

Используя профилировщик, мы обнаружили некоторые вопросы по оптимизации, которые хотелось бы решить на стороне движка, если это реально.

Все тесты проводились со страницей категории (список товаров), как наиболее востребованной в продвижении страницы. Очень бы хотелось совместно с вами добиться максимального ускорения загрузки данной страницы.

Среда тестирования

Для оценки скорости работы были использованы:

- php v7.4

- xdebug extension v3.1.1

- xdebug profiler для генерации отчетов

- Webasyst v2.4.1.636

- Shop-Script v8.21.0.49

- Emarket v7.0

- symfony/var-dumper

- В настройках режим разработчика **ОТКЛЮЧЕН**

Пояснение к пунктам

- Все расчеты суммируются. Т.е. результат последующих расчетов зависит от внесенных ранее изменений. В том порядке, в котором они указаны в документе.

- На скриншотах с профилировщиком время работы функций указаны в микросекундах.

- Низкие показатели по загрузке страницы связаны с работой профилировщика, поэтому для расчета примерного времени работы с выключенным профилировщиком все значения нужно делить на 5. Так как профилировщик замедляет работу php процесса в ~5 раз.

1. Кеширование результатов парсинга файлов шаблона

Самое важное замечание. Парсинг файлов theme.xml производится на каждый запрос. [В результатах работы профилировщика] (https://disk.yandex.ru/i/awKM8iDvN6dbLQ) выделены некоторые функции которые выполняются при каждом запросе:

Итого получается на каждый запрос потрачено лишних ~400 мс(80 мс без профил)

Решение:

Необходимо кешировать результаты работы парсинга фалов theme.xml:

Например если создать [файлы php с результатами в виде массивов](https://disk.yandex.ru/i/W_v8lCQ_Mrbftg) для каждой из тем и загружать эти файлы во время инициализации из кеша, то мы получим значительный прирост скорости работы всех сайтов на Shop-Script.

Добавив пример с загрузкой файлов из кеша мы получили **[прирост скорости в 128%](https://disk.yandex.ru/i/0-j8TK2NBgesvA)**

Добавив код, который исключает дублирование инициализации (см. ниже) мы получаем еще ~100мс и [прирост скокрости уже будет составлять 136%](https://disk.yandex.ru/i/94jkZ19AvCxPCA)

2. Дублирование инициализации

Дело в том, что парсинг xml файлов (для наследованных тем так же происходит парсинг родитеского theme.xml) шаблона производится на каждый запрос. Хуже того, он делает это дважды для каждой темы дизайна. Т.е. на примере нашей темы дизайна (site:theme.xml + shop:theme.xml) * 2.

Решение:

Если в файл кода метода [\waTheme::init добавить любой вывод (скриншот)](https://disk.yandex.ru/i/pdBAeJsUyDmcKA), то на витрине мы увидим что [инициализация выполняется дважды](https://disk.yandex.ru/i/ahVRRnDtxagEsA). Для тестирования мы добавили статическую переменную и выполняли проверку условия.

3. Отключение расчета "Промо Акций"

Рассмотреть возможность отключать весь блок "Маркетинга" на сайте, или на конкретных страницах, например, «Список товаров».

Решение:

Если например в \shopPromoProductPrices::loadPromoPrices на первой же строчке кода [выполнить return](https://disk.yandex.ru/i/_4XXHASShKQheg) то мы получим прирост еще в ~200 мс (40 мс без профил) а итоговый прирост [прирост скорости уже будет составлять 151%](https://disk.yandex.ru/i/rwpWi54mlI3i1A).

- Маркетинг дложен быть отдельным приложением, а не часть Shop-Script.

4. Работа методов \waRouting::getUrl и \shopConfig::getCurrency

Вам необходимо проверить работу данных функций на предмет ненужных действий. Функции [вызываются часто](https://disk.yandex.ru/i/wLBSdqBr6IYbZw).

Пример

На примере вызовы функции \shopConfig::getCurrency которая вызывается ~450 раз.

Мы добавили в код \shopConfig::getCurrency [простое кеширование через статические поля класса](https://disk.yandex.ru/i/FEyiPZV3QVTIlg). И получили прирост в производительности примерно в ~120 мс (24 мс без профил). Сайт при этом работает нормально, но так как у нас нет unit,integration и других тестов, мы не можем проверить как это решение повлияет в целом на фронтенд. По той же причине мы не тестировали работу \waRouting::getUrl. Но ~70 мс(14 мс без профил) которые занимает эта фунцкия, возможно тоже можно сократить.

ИТОГИ

Выполняя вышеописанные действия мы получили [прирост производительности в ~166%](https://disk.yandex.ru/i/IqAdr0DvP-D-Bg) или ~2c(400мс без профил) против ~1.2с(240 мс) на выполнение одного и того же запроса.

Надеемся, что удастся оказать содействие в ускорении этих и любых других моментов, которые позволят ускорить загрузку сразу всех клиентов на Shop-Script.