Сьогодні оптимізував роботу одного сайту і хочу дати кілька порад, які можуть стати в нагоді багатьом починаючим програмістам, особливо тим, хто по більшою мірою веде розробку на рівні тегів MODX.
До речі, відразу зазначу, що це сайт-візитка, і всі сторінки кешіруемие за винятком окремих блоків.
Отже, найголовніший мінус, з яким я зіткнувся. У більшості шаблонів контент сторінки виводився через призначений для користувача чанк, в якому вже був прописаний тег [[* content]]. Ось повний лістинг цього чанка:
Тут пропоную звернути увагу саме на конструкції типу [[* parent: is = `240`: then =` ... У чому ж тут проблема? Проблема в тому, що MODX-парсер працює не так, як, наприклад, php-інтерпретатор. За логікою речей тут має бути наступне: якщо ID батька поточного документа дорівнює 240, то виконується блок Then. За логікою Так, а на практиці Ні. Покажу простий приклад як обробляються умови на php, щоб показати, чого не відбувається. Ось простий код:
Так ось, в даному прикладі, якщо parent нічого очікувати дорівнює 240, то функція time () нічого очікувати виконано в принципі. При парсінгу MODX же вміст блоку виконається в будь-якому випадку, просто буде результат виведений на сторінці чи ні, визначить істинність умови.
В даному випадку незалежно від умови MODX-парсер виконав повністю блок Then, а тільки потім на основі умови вирішить виводити результат цього блоку чи ні. Тобто не залежно від того, який батько у документа, все блоки в цьому чанка будуть виконані. А між тим цих блоків тут чотири, при цьому два з них - НЕкешіруемий сниппет getPage. Тобто навіть якщо сторінка вже закеширувалася, кожен раз при зверненні до неї MODX буде обробляти ці сніппети, тому що вони некешіруемие. Як результат: 5-10 секунд на генерацію коду закеширувалася сторінки проти однієї секунди з виправленою логікою.
Тут ми підібралися до того, як же правильніше прописувати подібні речі. Моя порада: менше використовуйте чанкі, більше сніппети. Не дивлячись на те, що чанкі психологічно сприймаються більш простими елементами (так як в них ніби як HTML, а не виконуваний php), проте їх використання накладає додаткові витрати, так як додатково навантажують парсер. Плюс, як я писав тут. в чанка ви керуєте кешем елементів тільки на рівні поточного документа, а не на рівні всього сайту. Тому намагайтеся дотримуватися правила: будь-яка логіка в сниппета, оформлення в чанка.
Як же було б правильніше реалізувати логіку? 1. Створюємо чанк, який буде у нас шаблоном для виведення результату роботи сниппета.
На замітку: тут є два плейсхолдера: pre_content і post_content. При створенні чанкі, якщо не впевнені в тому, що для всіх плейсхолдеров будуть передані змінні, на всякий випадок створіть порожні Параметри для цього чанка. У нашому випадку це Параметри pre_content і post_content. Не знаю наскільки зараз пофіксити, але раніше парсер до 10-ти разів намагався «знайти» змінну, пережовуючи чанк.
2. Створюємо сниппет.
У цьому сніпеті ми не прописали додаткове кешування, але для нас зараз головне те, що блоки усередині умов будуть виконані тільки тоді, коли умова буде виконана. За рахунок цього ми на практиці дуже сильно скоротили час на генерацію сторінки. В результаті код не став заплутаніше, але продуктивність виросла сильно.
І наостанок порада: не зберігайте багато коду в шаблонах. На багатьох сайтах сторінки мають однакові шапку і підвал на всьому сайті (як правило тільки головна може істотно відрізнятися). Так ось створіть загальні чанк header і footer, і довантажувати їх в кожному шаблоні, щоб не довелося потім всюди міняти, якщо якийсь блок треба змінити. А то уявіть скільки рухів треба зробити, щоб поміняти дизайн і логіку на сайті, на якому штук 15 ось таких шаблонів:
Тобто ви розумієте про що я?
Думаю так, розумію. 99% розклад такий: не залежно від того, яке у вас умова на рівні шаблону (я про [[! If?), Чанкі [[$ fullTemplate]] і [[$ mobileTemplate]] будуть відпрацьовані в будь-якому випадку. Це особливо MODX-парсера. Це вам не чистий php, де якщо умова if () не виповнилося, то і всередині нього ніщо не виконається. А тут If - це навіть не функція, а просто тег (якщо говорити про шаблонізаціі). В результаті він або виведе, або не виведе результат. Але результат всередині в будь-якому випадку буде, тобто внутрішні теги відпрацювати.
Це одна з серйозних таких причин, по якій ми використовуємо modxSmarty, а не нативную шаблонізаціі MODX-а. На рівні Smarty це було б так:
Ось тут чітко буде або одне виконано, або інше.
Якщо хочете робити на чистому MODX-е, тоді не сниппет If викликати треба, а свій сниппет напишіть, який чітко за умовою буде викликати той чи інший чанк. return $ modx-> getChunk ($ chunkName);