Як заощадити на запитах і зробити ajax-форми

  1. Черговий компонент ... а навіщо? Кожен веб-розробник знає, що кількість запитів до бази даних на...
  2. Хм, а як же він це робить?
  3. І що тепер з цим робити?

Черговий компонент ... а навіщо?

Кожен веб-розробник знає, що кількість запитів до бази даних на сторінці треба зменшувати. Знають це і в компанії 1С-Бітрікс, і краще нашого. Вони розробили різні механізми кешування , Як для всієї сторінки, так і для окремих компонентів. Питається, навіщо придумувати щось ще, якщо створено таку кількість кешей?

Розглянемо дві ситуації. Перша - шалена оптимізація сторінок і наявність форм на сторінці. У чому проблема більшості форм (веб-форми, зворотній зв'язок, форма додавання Інфоблоки і реєстрація / авторизація)? Вони роблять запити незважаючи ні на що (особливо для капчи - її НЕ закешіруешь), а оптимізація то, як ми домовилися вище, шалена. Так що постає питання - як позбутися від них? Раніше, в ИнтерВолга, ми бачили єдиний варіант: кастомизация компонента, щоб він робив якомога менше запитів (але при цьому від деяких запитів позбутися не вдасться ніяк - наприклад, генерація капчи).

Друга проблемна ситуація - HTML-кешування сторінок. Ми включили його на головній сторінці нашого сайту intervolga.ru, але воно не запрацювало через двох форм в шапці сайту. Генерація капчи в цих формах запускала сесію, а це означало повне виконання сторінки без HTML-кешування. При відключенні капчи з форм зворотного зв'язку в немислимих кількостях посипався спам.

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

Так що ж він робить?

Вирішувати проблему почали з малого - з форми авторизації. Нехай, мовляв, на сторінці в шапці буде посилання, при натисканні на яку буде по AJAX'у довантажуватися справжня форма входу на сайт. І це справді добра пропозиція - ми позбудемося одного, нехай і не найтяжчої компонента при завантаженні сторінки, а отримувати його буде тільки той, кому дійсно треба авторизуватися. Про деталі реалізації буде сказано нижче, зараз же тільки покажемо наочно, що витворяє компонент intervolga: ajax.component.

Подивимося на процес завантаження окремо взятої сторінки окремо взятим користувачем.

Подивимося на процес завантаження окремо взятої сторінки окремо взятим користувачем

UML Sequence-діаграма звичайної завантаження сторінки

«Інших компонентів» на сторінці може бути з добрий десяток, тому всі вони діаграмі представлені однією лінією життя. Знавці Бітрікс скажуть: «є ж ще і агенти, події при виконанні сторінки, шаблон, пролог-епілог, файл init. php », - і будуть праві. Але в даній моделі ми розглядаємо тільки «тіло» сторінки, так як оптимізуємо її, а не весь Бітрікс.

Як можна побачити, завантаження сторінки відбувається синхронно, кожен компонент по черзі підключається, виконує свої запити, формує HTML і повертає його на сторінку. Коли прохід закінчений, після виконання епілогу, Бітрікс показує сторінку користувачеві.

Тепер подивимося на ту ж сторінку, але з компонентом intervolga: ajax.component, налаштованим на роботу з формою авторизації.

UML Sequence-діаграма завантаження сторінки з AJAX-компонентом

Наш компонент робить запитів до БД при завантаженні сторінки - тільки виводить посилання з текстом «Увійти» ну або яким вкажете в налаштуваннях.

Наш компонент робить запитів до БД при завантаженні сторінки - тільки виводить посилання з текстом «Увійти» ну або яким вкажете в налаштуваннях

За рахунок цього сторінка стала легше, робить менше запитів, і підключає менше javascript'а (всі пам'ятають про форму авторизації через соціальні мережі?). Краса, одним словом.

Але компонент не пропав - він завантажиться при кліці на засланні. Чи піде AJAX-запит, повернеться HTML компонента і ми побачимо форму авторизації у спливаючому вікні.

Ідея виявилася настільки захоплюючою, що компонент відразу проектувався універсальним - на місці авторизації може бути будь-який компонент 2.0 продукту 1С-Бітрікс, в тому числі і Ваші власні або будь-які компоненти сторонніх модулів .

Нижче ви можете побачити інші компоненти, що отримуються аналогічним чином по AJAX.

Нижче ви можете побачити інші компоненти, що отримуються аналогічним чином по AJAX

Форма зворотного зв'язку

Форма зворотного зв'язку

список новин

список новин

Детальний опис новини

Підводячи підсумок, можна сміливо заявити: розроблений компонент intervolga: ajax.component дозволяє прибрати зі сторінки запити будь-якого компонента, зробивши його доступним у спливаючому вікні.

Хм, а як же він це робить?

Реалізація - найцікавіша частина компонента, навіть цікавіше, ніж ідея. Спочатку (нагадую, завдання зводилася тільки до авторизації у спливаючому вікні) виникла дилема - як виводити посилання «Увійти»? Було кілька варіантів.

  1. Вивести посилання в шаблоні сайту, javascript винести в скрипти шаблону сайту і не мучитися. Поганий варіант, неуніверсальність, хоч і найшвидший.
  2. Створити альтернативний шаблон компонента bitrix: system.auth.form, який виводив би посилання для отримання справжнього компонента. Але тоді виконувався б component. php, а з ним і запити. Ні, не треба так.
  3. Створити свій компонент авторизації, який в одному випадку б виводив посилання, а в іншому - робив запити прямо як справжня форма, використовували б копіпаст з bitrix: system.auth.form. Але хотілося універсальності, щоб можна було «зааджаксіть» будь-який компонент.

Зупинилися на проміжному рішенні, яке об'єднує 2-ий і 3-ий варіант. Був створений свій компонент, але і без свого шаблону для bitrix: system.auth.form не обійшлося.

Отже, повільно і по-порядку. Розроблений компонент - це обгортка над будь-яким іншим компонентом. Ви викликаєте intervolga: ajax.component, а він вже викликає, наприклад bitrix: main.profile (викликається компонент ми стали називати «внутрішнім», тому будемо дотримуватися цього терміна і тут). У настойках нашої обгортки вказується, який компонент і який його шаблон повинні бути внутрішні, а так само до налаштувань обгортки динамічно додаються налаштування внутрішнього компонента (sic!). Далі обгортка працює за двома альтернативними сценаріями. У звичайному випадку (що таке незвичайний випадок - далі) вона підключає свій стандартний шаблон.default, який виводить посилання.

default, який виводить посилання

Було потрібно після натискання на посилання робити AJAX-запит і поміщати отриманий HTML у спливаючу форму. Це було найменшої проблемою - ми скористалися JS-плагіном для спливаючих форм.

На засланні, по якій відбувається перехід, зашивається ID нашого компонента (ми ж не хочемо, натиснувши на кнопку «Увійти» побачити на сайті форму «Станьте». Назва параметра, в якому передається ID, можна налаштовувати в компоненті.

Запит робиться на ту ж саму сторінку, але з додатковим параметром, наприклад AJAX_IID = bitrixsystemauthform. Компонент перевіряє цей параметр, а так же заголовок HTTP_X_REQUESTED_WITH. І це не дуже безпечно, факт залишається фактом. Заголовки чудово підробляються. Але цей варіант нічим не гірше, ніж рішення передавати особистий ключ у запиті в іншої реалізації AJAX-форми авторизації від Антона Долганін. Ключ підробити ще простіше.

Переконавшись, що йде AJAX-запит, а ID в запиті підходить до її власним, обгортка починає виконання другого альтернативного сценарію - очищає буфер, стираючи все, що було виведено раніше на сторінці, виводить внутрішній компонент (в даному випадку це авторизація) і, без зайвих слів, закінчує роботу сторінки за допомогою die ().

Як не дивно, чи не більшу частину часу зайняла розробка не самого компонента (файлу class. Php - так-так, ми вважаємо за краще робити компоненти відразу класами) а його файлу настроек.parameters. php.

На допомогу прийшло недокументоване API . Використовувалися такі методи, як:

  • CComponentUtil: GetComponentsTree () - щоб отримати розділи та підрозділи компонентів, а так само самі компоненти;
  • CComponentUtil: GetTemplatesList () - щоб отримати список шаблонів обраного компонента;
  • CComponentUtil: GetComponentProps () - щоб отримати настройки компонента;
  • CComponentUtil: GetTemplateProps () - щоб отримати додаткові налаштування шаблону компонента.

В результаті, вдалося зробити повноцінну обгортку - при налаштуванні intervolga: ajax.component ви обираєте будь-який компонент і налаштовуєте його тут же. Більш наочно - на скріншоті нижче.

А так виглядає код, що викликає intervolga: ajax.component.

Щоб не плутати налаштування нашого intervolga: ajax.component з тими, які будуть передані у внутрішній компонент - до параметрів внутрішнього додали префікс «INNER_».

Таким чином ми вмудрились не накопіпастіть, і створити досить-таки універсальний спосіб підключення будь-яких компонентів (до речі, в налаштуваннях intervolga: ajax.component можна вибрати intervolga: ajax.component як внутрішній компонент).

Другою проблемою на шляху до реалізації стали стилі і скрипти. Внутрішній компонент може як мати файли script.js і styles. css в папці з шаблоном (тоді Бітрікс підтягує їх автоматично), так і підключати їх самостійно за допомогою $ APPLICATION-> SetAdditionalCSS () і $ APPLICATION-> AddHeadScript () в component_epilog. php. Підключати-то підключає, але виводяться вони в секції head сторінки, яку ми не повертаємо при AJAX-запиті (нагадування - обгортка при запиті повертає тільки той HTML, який потрібно вставити в спливаюче вікно.

Початковий варіант - підключати script.js, styles. css і component_epilog. php внутрішнього компонента був не дуже успішний. Тоді зробили простіше - друк стилів і скриптів перенесли з head в область відразу за кодом внутрішнього компонента, тобто стилі йшли однією порцією разом з кодом, який повинні були стилізувати. Дуже зручно.

І що тепер з цим робити?

Тепер, отримавши в свої руки такий потужний інструмент, можна переглянути багато елементів сайту, спочатку проектувати їх по-новому. Проект, для якого створювався компонент, тільки на підході, так що про перші враження поки рано говорити, але немає таких проблем, які не можна було б вирішити.

Оцініть статтю:

А навіщо?
Хм, а як же він це робить?
І що тепер з цим робити?
А навіщо?
Питається, навіщо придумувати щось ще, якщо створено таку кількість кешей?
У чому проблема більшості форм (веб-форми, зворотній зв'язок, форма додавання Інфоблоки і реєстрація / авторизація)?
Так що постає питання - як позбутися від них?
Так що ж він робить?
Всі пам'ятають про форму авторизації через соціальні мережі?
Хм, а як же він це робить?