Здрасте!
Поговорим про самое спорное телодвижение компании Битрикс — технологию «Композитный сайт».
Спорное оно потому, что ребята запатентовали технологию, которая, по моему мнению, не тянет даже на курсовую 3 курса профильной специальности.
Ну да ладно, это ж маркетологи.
В статье рассмотрены:
- сама технология «Композитный сайт»
- альтернатива данной технологии «CompoJax» (через ДЖ)
- примеры кода, для той и другой технологии
- пример внедрения CompoJax в любую CMS на примере WordPress
Все вкусности внутри, го под кат.
INTRO
Честно, не понимаю какой был смысл патентовать технологию на 1-2 сотни строк кода, да к тому же и совсем не инновационную, это правда уже вопросы к «патентному бюро», так что пофиг.
Погнали!
Технология композитный сайт
Громко, конечно, называть это технологией, но все же пусть будет так.
Что же это такое?
Цитата с сайта Битрикс:
Уникальная технология производства сайтов объединяет в себе высокую скорость загрузки статического сайта и все возможности динамического сайта.
Пользователь мгновенно получает контент страницы.
Обещают даже ускорение в 100 раз, правда бенчмарки не предоставили.
Ну это опять вопрос к маркетологам, а это, честно, не по моей части.
Алгоритм работы следующий:
То, что выделено красным, выполняется параллельно.
Пояснять не буду, тут все понятно.
/*
* включение в компоненте и в шаблоне
*/
$component->setFrameMode(true);
$template->setFrameMode(true);
/*
* динамический фрейм
*/
$frameBuffer = new Bitrix\Main\Page\FrameBuffered("id_container_buffer");
$frameBuffer->begin("сообщение, которое будет выведено вместо контента");
echo "динамические данные";
$frameBuffer->beginStub();
echo "статические данные";
$frameBuffer->end();
/*
* статический фрейм
*/
$frame = new \Bitrix\Main\Page\FrameStatic("id_container_static");
$frame->setStub("сообщение, которое будет выведено вместо контента");
$frame->startDynamicArea();
echo "динамические и статические данные";
$frame->finishDynamicArea();
Код снят с документации и подглядками в исходники. Сильно не углублялся, да это мне и не нужно, есть же CompoJax. Запускать в компонентах не пробовал, скажу лишь, что на страницах и шаблоне сайта он не завелся. Кому интересно — может почитать документацию, но, на самом деле не советую, т.к. после 9-ти страничного теоретического петтинга, вы увидите почти те же самые строчки кода.
CompoJax
Собственно, «технология» делающая практически тоже самое, только без пафоса, патента, проще, прозрачнее + PJAX.
Разделить технологию можно на 2 части:
- Композит
- PJAX
Для первой ничего не требуется, можно смело юзать.
Для второй составляющей, необходимо наличие библиотек jQuery и PJAX.
Алгоритм работы следующий:
Собственно, вот и все.
Алгоритмически «технологии» не одинаковы, так что нарушения патента, в принципе, нет. В патент не углублялся, но если придет повестка в суд сделаю в статье update. Ниже представлены все возможности CompoJax, параметры PJAX и способы его кастомизации. Данный код можно использовать везде, в компонентах, шаблонах, своих классах, неважно.
use Jugger\Context\CompoJax;
/*
* простой вызов, без параметров
*/
if (CompoJax::begin("id_container")) {
// ...content...
CompoJax::end();
}
/*
* указываем картинку лоадер
*/
$params = [
"loading" => "<img src='http://loader.gif' alt='загрузка'>",
];
if (CompoJax::begin("id_container", $params)) {
// ...content...
CompoJax::end();
}
/*
* указываем URL к которому делается запрос на вывод данных
* таким образом Вы сможете динамически подгружать данные откуда угодно
*/
$params = [
"url" => "/api/methodName?param1=...",
];
CompoJax::begin("id_out_container", $params);
/*
* можно перегрузить логику обработки ответа
*/
$js = <<<JS
function(xhr, params) {
// xhr - объект XMLHttpRequest
// params - объект содержащий параметры блока: id - индектификатор контейнера, url - адрес на который отправлялся запрос
if (xhr.status == 200) {
document.getElementById(params.id).innerHTML = xhr.responseText;
}
else {
// обработка ошибки
}
};
JS;
$params = [
"callback" => $js,
];
if (CompoJax::begin("id_container", $params)) {
// ...content...
CompoJax::end();
}
/*
* для работы с PJAX необходимо добавить соответствующий пункт в параметрах,
* структура представлена на примере ниже,
* добавлять можно несколько вариантов привязки
*/
$params = [
"pjax" => [
// по умолчанию контейнер самого compoJax блока
// "container" => "#id_container"
[
"selector" => "a", // обязательный параметр
],
[
"selector" => "form#pjax-form",
"container" => "#pjax-form-contaner",
// параметры самого PJAX (подробнее: https://github.com/defunkt/jquery-pjax#pjax-options )
"options" => [
"push" => false,
"scrollTop" => false,
],
],
// правило ниже не примениться, т.к. не указан 'selector'
[
"container" => ".fail-container"
]
],
];
if (CompoJax::begin("id_container", $params)) {
// ...content...
CompoJax::end();
}
CompoJax включен в либу Juggernaut, однако, вы можете скачать его отдельно (всего 1 класс), ссылки ниже.
Не только для Битрикс
Как я заикнулся выше, данную технологию можно использовать не только в Битрикс, но и в любой CMS.
На самом деле, нужно просто наследоваться от CompoJax и перегрузить методы end и clearBuffer.
Первый для вывода динамического контента, второй для чистки буфера уже выведенного контента.
Рассмотрим перегрузку данных методов на примере WordPress:
class WpCompoJax extends CompoJax
{
protected static function clearBuffer() {
/*
* в WP вывод происходит в последнюю очередь,
* поэтому чистить ничего не нужно
*/
}
public static function end() {
ob_end_flush();
self::processPjax(); // необходим для вывода PJAX кода, можно убрать если не нужен PJAX
wp_die();
}
};
Ну, вот и все.
В принципе, все готово, все круто, все работает. Осталось только добавить кеширование и вообще будет замечательно. Это будет добавлено в скором времени, возможно.
Juggernaut: https://github.com/irpsv/juggernaut.bitrix
CompoJax: длинная ссылка на github
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (26)
nikitasius
20.07.2016 10:52Я учил PHP4 за 21 день в 2008м для написания двух сайтов, так что я далек от сего кода.
Такой вопрос:
сие нечто иное как приблуда, которая дергает с сервера кешированные/скомпиленные файлы и отдает ответ юзеру череззамену контента div'аpajax?
или
это другая приблуда, которая выдает совместимый с pajax контент, который последний вставит в страницу?rpsv
20.07.2016 11:19-2Композит — кеширует куски страницы, затем выплевывает их подгружая через JS.
CompoJax — выплевывает куски страницы подгружая через JS (без кеша) + используя PJAX можно обновлять содержание блока (кусок страницы), без перезагрузки всей страницы, при чем URL подставиться нужный (этим страдает коробный AJAX).
Ну собственно чтобы заработал PJAX, куски страницы должны выдаваться без header и footer.
P.S.: Не помешало бы еще и выучить русский язык. Дело вкуса конечно, но читать то, что вы написали, слегка трудно и сильно странно.michael_vostrikov
20.07.2016 11:51То есть для подгрузки 3 частей страницы надо 3 раза обратиться к серверу?
rpsv
20.07.2016 20:57Да, именно так.
Я считаю нет смысла пользователю ждать пока загрузятся все части, если ему нужна только верхняя часть (если говорить про длинные лендинги и др. объемные страницы).
nikitasius
21.07.2016 01:29можно обновлять содержание блока (кусок страницы), без перезагрузки всей страницы
и уж
Композитный сайт: технология Битрикс в каждую CMS
Такая механика уже сто лет как используется на практике. Да и есть вариант много интереснеее:- JS подгружает шаблон в нужный div
- далее JS запрашивает у страницы JSON по которому наполняет этот самый DIV
- +JS, который отвечает за исполнения тех или иных скриптов, которые генерит динамика (графики, или табличеи и т.д.)
Ничего не имею против битрикса, кроме как не использую его, и не пишу на PHP, но рад, что и на вашей улице солнце (или как там говорят).rpsv
21.07.2016 07:44Сто лет назад не было JS ;-)
Где такая древняя механика в: Drupal, WordPress, Joomla, HostCMS, NetCat,… ???
А чем вариант который описали вы отличается от CompoJax?nikitasius
21.07.2016 10:07Где такая древняя механика в: Drupal, WordPress, Joomla, HostCMS, NetCat,… ???
Я про самописные CMS. Из инетовских — знаю, что IPB умеет комменты по JS подгружать.
А чем вариант который описали вы отличается от CompoJax?
Хз, не смотрел ваш combojax. Если не отличается — подтверждает, что сие используется программистами. Другое дело, что каждый сам с усами и не думает свои решения публиковать в виде библиотеки в силу лени (написать универсальный код) или каких-то других факторов, сопряженных с той же ленью.
Delphinum
20.07.2016 10:55Может я не совсем понял технологию, но разве тот же Smarty не поступает аналогичным образом «за кулисами»?
rpsv
20.07.2016 11:13-1Вероятно.
Smarty — по сути же шаблонизатор, поправьте если не прав, а композит и compojax, более мелкие вещи в сравнении.Delphinum
20.07.2016 11:24В общем да, Smarty это шаблонизатор со своим синтаксисом, парой плюшек и кешированием. Кеширование выполняется двумя механизмами: кеширование созданного из синтаксиса Smarty PHP кода для повторного использования; кеширование полученных кусков HTML. Но кеширование это пол дела, для удобства и повторного использования крайне важны такие конструкции, как include и extend, коих, на сколько я понимаю, в решении от Битрикса или в CompoJax нет.
rpsv
20.07.2016 11:44-1Спасибо, как обычно подкинули пищу для размышлений)))
Я думаю во избежания велосипедства, лучше все таки подключить Smarty как шаблонизатор к самому Битрикс, т.к. у CompoJax суть не в этом.Delphinum
20.07.2016 11:49Многим еще нравится Twig, но я не вижу между ними особой разницы. Как показал мой опыт, декомпозиция экранов очень важна, но ее невозможно правильно организовать без подключения компонентов и наследования экранов. Другими словами, ваши экраны должны быть как хорошие классы, в них не должно быть копипасны. Лично я даже элементы формы реализую в виде отдельных виджетов и подрубаю в форму как то так:
{extends "./../form.tpl"} {block "action"} {assign var="action" value="/panel/country/update/{$entity->getId()}"} {/block} {block "body"} {include "./../../widget/form/input/string.tpl" label="Название" name="data[name]" value={$entity->getName()|escape}} {include "./../../widget/form/input/string.tpl" label="Код" name="data[code]" value={$entity->getCode()|escape}} {include "./../../widget/form/input/checkbox.tpl" label="Скрыть" name="data[is_hidden]" value={$entity->isHidden()}} {/block}
Shadez
20.07.2016 13:18Инклюд на каждый инпут формы — не слишком дорого получается?
Delphinum
20.07.2016 18:35Если шаблонизация становится «узким местом», всегда можно избавится от одного-двух уровней декомпозиции. На данный момент наш проект больше страдает от отсутствия стандартов написания экранов, от чего каждый инпут формы каждый из разработчиков реализует по своему (утрирую конечно).
С другой стороны, не забывайте о кешировании.
xRay
У Битрикса, на сколько я помню, готовые к отдаче пользователю куски страниц складываются в кеш на диск. В этом и ускорение что не дерагется вся махина, а отдается из кеша.
irbisadm
Вы же понимаете, что кеширование на диск/в память это дело нескольких десятков строк кода? :)
xRay
Конечно :)
Source
А как им удалось это запатентовать то? Этой технологии уже 100 лет в обед…
статья 2011 года, статья 2009 года и скорее всего и более ранние упоминания можно найти, ещё тех времён, когда аббревиатура AJAX в употребление ещё не вошла.
rpsv
Если об этом просто писали, то это ничего не значит.
Они же не патентовали.
И патент был не на абривиатуру AJAX, а на способ загрузки страницы
Source
Это понятно, про аббревиатуру я написал просто, чтобы подчеркнуть насколько давно на практике используется этот способ загрузки страницы. Ну а то, что его не патентовали… так что ж теперь каждый алгоритм патентовать?
sectus
А патент, по моему, на код в принципе получить нельзя. Только на какое-нибудь устройство. А вот зарегистрировать, чтобы защищать авторские права можно.
rpsv
Можно полезную модель или изобретение патентовать.
Но есть условие: должна быть мировая новизна.
ГДЕ она здесь, не понятно…