[Разработка веб-сайтов, PHP, Drupal, Программирование] #lazy_builder (не путать с lazy load) в Drupal 8/9
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Продолжая изучать Drupal, мы наткнулись на очень интересную технологию, которая в него встроена. И которая, на наш взгляд, используется неоправданно мало. И совершенно зря. Потому что подход, который использует эта технология, позволяет мгновенно отдать высоконагруженную (или просто долго формирующуюся) страницу пользователю, а потом «доотдать» ему данные, требующие много времени на формирование. И изучая эту технологию, мы столкнулись с тем, что нет ни одного простого объяснения, что это и как это запустить. Нет, объяснения-то есть. Простых нету. Сейчас мы попытаемся восполнить эту неприятность.
Общее описание
Итак, у нас есть страница, которая по каким-то причинам долго формирует часть данных. Причины могут быть разными — большой объём вычислений, большой объём данных, долгие запросы к какой-нибудь медленной базе данных, или вообще надо лезть на сторонний сервис, с которого получить информацию, которую потом ещё и обработать надо. Причины — неважны. Важно, что на нашей странице есть данные, которые мы может отдать сразу — заголовки, подвал, какие-то картинки, ещё кучу обрамления, текста, реклама, в конце концов. А есть данные, которые нам надо «добыть», и на это уйдёт какое-то количество времени.
Так вот. Обычно эту задачу решают через механизм «ленивой загрузки» — грузится облегчённая версия страницы, а потом срабатывает скрипт lazy loading, который с помощью JavaScript сходит на бекенд, заберёт оттуда данные и положит их в нужные места. Но у ленивой загрузки есть куча минусов. Начиная с того, что если, например, наши данные отдаются только авторизованному пользователю, то нам надо дополнительно авторизовать этот ленивый скрипт. Также нам всегда нужен включённый JavaScript. Эта «ленивая вещь» не очень хорошо дружит в поисковыми роботами. Ну и так далее.
А создатели Drupal, оказывается, молодцы. И предлагают нам ещё один механизм, который лишён почти всех минусов lazy loading'а. И называется этот механизм — «ленивый построитель» — lazy builder. Он работает, как всё гениальное — очень просто.
На то место в twig-шаблоне, где нужно вывести «тяжелые» данные, мы кладём обычную (почти) переменную, совершенно обычным способом, вот так: {{ lazy_data }}. А вот в препроцессоре, в котором мы готовим эту переменную, мы должны сказать ей волшебные слова, чтобы она стала lazy builder'ом. Выглядит это так:
$variables['lazy_data'] = [
'#create_placeholder' => TRUE, // - это необязательно, её Drupal сам умеет включать.
'#lazy_builder' => [ // - это те самые волшебные слова, из-за которых всё работает.
//... чуть ниже будет подробнее
],
],
];
И теперь Drupal, когда будет рендерить страницу, на место этой переменной поставит JavaScript-плейсхолдер, а сами данные формировать в момент рендера не будет. То есть — эта страница сформируется быстро, и так же быстро будет отдана пользователю. А уже потом, когда она будет показана браузером на экране, сработает этот плейсхолдер, который полезет на бэкэнд и скажет ему — «я готов, гони данные». Бэкэнд эти данные спокойно сформирует и отдаст. И они будут вставлены на то место, где они и должны быть.
Вот и всё! И не надо никакой дополнительной авторизации — она уже была произведена на бэкэнде. И не надо подключать никаких дополнительных скриптов — Drupal сам обо всём позаботится. И не нужны никакие дополнительные API точки входа, которые надо дополнительно писать и обслуживать. Не надо никаких уточнений — что за данные вам нужны — всё это уже было сделано на бэкэнде. Мы просто кусок «строительства страницы» отложили на потом. Вот и всё, что мы сделали.
И самое гениальное здесь то, что если у пользователя не включен JavaScript — то Drupal сам это распознает и сформирует эти тяжёлые данные сразу, без использования плейсхолдера. То есть — как будто бы никакой механиз отложенного строительства и не существует. Поисковые роботы будут счастливы, что им не надо разбираться с самописными ленивыми загрузками, они получат обычную страницу. Ну а подождать несколько секунд эту страницу для них не так критично, как для человека.
А теперь немного технических подробностей, как со всем этим взлететь это сделать.
Повторимся — в twig-шаблоне мы пишем как обычно — просто кладём переменную в нужное нам место. И всё, больше никаких телодвижений предпринимать не нужно.
В препроцессоре шаблона, в котором нам надо сформировать эту переменную, мы пишем «волшебные слова», чтобы она стала «ленивой» и пишем, что она должна вызвать для ленивого рендера нашей переменной:
$variables['lazy_data'] = [
'#create_placeholder' => TRUE, // - это необязательно, её Drupal сам умеет включать.
'#lazy_builder' => [ // - это волшебные слова, из-за которых всё работает.
'имя_модуля.lazy_renderer:renderBigData', [ // - это имя сервиса, который будет вызываться. Важно, что это именно сервис.
'info' => 'Важная информация', // - это просто параметры, которые ты отдаёшь в шаблон. См. ниже
'params' => ['foo' => 'boo'],
'something_else' => 11
],
],
];
Теперь нам надо сделать Drupal-овский «сервис», который и будет заниматься формированием наших больших данных. Для этого в файле имя_модуля.service.yml, который лежит в корне нужного модуля (не обязательно самописного), мы должны объявить этот сервис (имя_модуля.lazy_renderer), который будет вызываться для формирования того, что надо вывести в переменную 'lazy_data', которая потом пойдёт в ту заглушку, в дом который построил Джек.
В этом сервисе делаем функцию renderBigData, которая и будет вызываться. И вот эта функция должна вернуть ссылку на шаблон, который будет отрендерен и будет вставлен в нужное место страницы, в доме который построил Джек.
Но в эту функцию хочется же передать что-нибудь, да? Вот как это делается.
Во-первых, напоминаем, что для того, чтобы продать что-нибудь ненужное, надо сначала купить что-нибудь ненужное, а для того чтобы использовать шаблон для рендера, его надо сначала объявить. То есть — в файле имя_модуля.module, в функции function promotion_theme(...) надо вернуть, вместе с остальными заготовками шаблонов, заготовку нового шаблона:
'my_template_for_lazy_building' => [
'variables' => [
'info' => '',
'params' => [],
'something_else' => 1
],
],
А дальше всё просто — в сервисе, в функции, подготавливается всё, что нужно, и этот свежеобъявленный шаблон возвращается на рендер, передав ему то, что тебе нужно ему передать.
А у этого шаблона, в свою очередь, есть свой препроцессор, который сработает при попытке Drupal отрендерить шаблон. В этот момент препроцессор получит те переменные, которые объявлены и переданы.
То есть, технически это выглядит так:
// Смотрим выше на вызов сервиса из нашей переменной:
// 'имя_модуля.lazy_renderer:renderBigData'
// и сопоставляем класс:
class lazy_renderer {
public function renderBigData($info, $params, $something_else) {
//Обрати внимание на переменные функции
//Что-то тут делаем, готовим данные.
return [
'#theme' => 'my_template_for_lazy_building',
'#info' => $info,
'#params' => $params,
'#something_else' => $something_else
];
}
}
Сам twig-шаблон должен лежать в каталоге template модуля, само собой.
Вот и всё.
И ещё раз, чтобы подытожить «кто на ком стоял»:
- У нас есть переменная «lazy_data». Мы её кладём в twig-шаблон какой-то страницы, как простую переменную.
- В препроцессоре мы её формируем. И говорим ей — что она «ленивая» и что она должна вызвать сервис ('имя_модуля.lazy_renderer:renderBigData'), который вернёт шаблон (другой, 'my_template_for_lazy_building') на рендер. Этот шаблон отрендерится и вставится на место 'lazy data'.
- Не забываем наш шаблон объявить.
Надеемся, что смогли просто, но при этом максимально подробно, рассказать про технологию Lazy Builder.
Спасибо за внимание.
===========
Источник:
habr.com
===========
Похожие новости:
- [Информационная безопасность, Разработка веб-сайтов, Расширения для браузеров, Браузеры] Яндекс отключил расширения с аудиторией в 8 млн пользователей. Объясняем, почему мы пошли на такой шаг
- [PHP, Программирование] События в OpenCart
- [Программирование, C++, Проектирование и рефакторинг] Как легко и просто модернизировать код на C++ (перевод)
- [Программирование, Компиляторы, C, Разработка под Windows] Использование SEH в 32 разрядных приложениях Windows с компилятором Mingw-W64
- [Программирование, ReactJS] Создание React-компонентов с помощью Hygen (перевод)
- [Программирование, Разработка под iOS, Разработка мобильных приложений, Swift] Приложение на SwiftUI в AppStore – сложности разработки
- [Разработка веб-сайтов, Программирование, Исследования и прогнозы в IT, Облачные сервисы] Самые популярные языки программирования для бэкенда: для чего они подходят лучше всего и какие компании их используют (перевод)
- [Реверс-инжиниринг, Программирование микроконтроллеров, Прототипирование, Интернет вещей, DIY или Сделай сам] Подключаемся к станку по изготовлению профлиста и считываем из него прокатную длинну
- [Тестирование IT-систем, Программирование, Java, IT-стандарты, Промышленное программирование] Принцип слоеного теста
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] Вопросы для собеседования по хукам React (перевод)
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_php, #_drupal, #_programmirovanie (Программирование), #_lazy_builder, #_drupal, #_php, #_lazy_load, #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_php, #_drupal, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:26
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Продолжая изучать Drupal, мы наткнулись на очень интересную технологию, которая в него встроена. И которая, на наш взгляд, используется неоправданно мало. И совершенно зря. Потому что подход, который использует эта технология, позволяет мгновенно отдать высоконагруженную (или просто долго формирующуюся) страницу пользователю, а потом «доотдать» ему данные, требующие много времени на формирование. И изучая эту технологию, мы столкнулись с тем, что нет ни одного простого объяснения, что это и как это запустить. Нет, объяснения-то есть. Простых нету. Сейчас мы попытаемся восполнить эту неприятность. Общее описание Итак, у нас есть страница, которая по каким-то причинам долго формирует часть данных. Причины могут быть разными — большой объём вычислений, большой объём данных, долгие запросы к какой-нибудь медленной базе данных, или вообще надо лезть на сторонний сервис, с которого получить информацию, которую потом ещё и обработать надо. Причины — неважны. Важно, что на нашей странице есть данные, которые мы может отдать сразу — заголовки, подвал, какие-то картинки, ещё кучу обрамления, текста, реклама, в конце концов. А есть данные, которые нам надо «добыть», и на это уйдёт какое-то количество времени. Так вот. Обычно эту задачу решают через механизм «ленивой загрузки» — грузится облегчённая версия страницы, а потом срабатывает скрипт lazy loading, который с помощью JavaScript сходит на бекенд, заберёт оттуда данные и положит их в нужные места. Но у ленивой загрузки есть куча минусов. Начиная с того, что если, например, наши данные отдаются только авторизованному пользователю, то нам надо дополнительно авторизовать этот ленивый скрипт. Также нам всегда нужен включённый JavaScript. Эта «ленивая вещь» не очень хорошо дружит в поисковыми роботами. Ну и так далее. А создатели Drupal, оказывается, молодцы. И предлагают нам ещё один механизм, который лишён почти всех минусов lazy loading'а. И называется этот механизм — «ленивый построитель» — lazy builder. Он работает, как всё гениальное — очень просто. На то место в twig-шаблоне, где нужно вывести «тяжелые» данные, мы кладём обычную (почти) переменную, совершенно обычным способом, вот так: {{ lazy_data }}. А вот в препроцессоре, в котором мы готовим эту переменную, мы должны сказать ей волшебные слова, чтобы она стала lazy builder'ом. Выглядит это так: $variables['lazy_data'] = [
'#create_placeholder' => TRUE, // - это необязательно, её Drupal сам умеет включать. '#lazy_builder' => [ // - это те самые волшебные слова, из-за которых всё работает. //... чуть ниже будет подробнее ], ], ]; И теперь Drupal, когда будет рендерить страницу, на место этой переменной поставит JavaScript-плейсхолдер, а сами данные формировать в момент рендера не будет. То есть — эта страница сформируется быстро, и так же быстро будет отдана пользователю. А уже потом, когда она будет показана браузером на экране, сработает этот плейсхолдер, который полезет на бэкэнд и скажет ему — «я готов, гони данные». Бэкэнд эти данные спокойно сформирует и отдаст. И они будут вставлены на то место, где они и должны быть. Вот и всё! И не надо никакой дополнительной авторизации — она уже была произведена на бэкэнде. И не надо подключать никаких дополнительных скриптов — Drupal сам обо всём позаботится. И не нужны никакие дополнительные API точки входа, которые надо дополнительно писать и обслуживать. Не надо никаких уточнений — что за данные вам нужны — всё это уже было сделано на бэкэнде. Мы просто кусок «строительства страницы» отложили на потом. Вот и всё, что мы сделали. И самое гениальное здесь то, что если у пользователя не включен JavaScript — то Drupal сам это распознает и сформирует эти тяжёлые данные сразу, без использования плейсхолдера. То есть — как будто бы никакой механиз отложенного строительства и не существует. Поисковые роботы будут счастливы, что им не надо разбираться с самописными ленивыми загрузками, они получат обычную страницу. Ну а подождать несколько секунд эту страницу для них не так критично, как для человека. А теперь немного технических подробностей, как со всем этим взлететь это сделать. Повторимся — в twig-шаблоне мы пишем как обычно — просто кладём переменную в нужное нам место. И всё, больше никаких телодвижений предпринимать не нужно. В препроцессоре шаблона, в котором нам надо сформировать эту переменную, мы пишем «волшебные слова», чтобы она стала «ленивой» и пишем, что она должна вызвать для ленивого рендера нашей переменной: $variables['lazy_data'] = [
'#create_placeholder' => TRUE, // - это необязательно, её Drupal сам умеет включать. '#lazy_builder' => [ // - это волшебные слова, из-за которых всё работает. 'имя_модуля.lazy_renderer:renderBigData', [ // - это имя сервиса, который будет вызываться. Важно, что это именно сервис. 'info' => 'Важная информация', // - это просто параметры, которые ты отдаёшь в шаблон. См. ниже 'params' => ['foo' => 'boo'], 'something_else' => 11 ], ], ]; Теперь нам надо сделать Drupal-овский «сервис», который и будет заниматься формированием наших больших данных. Для этого в файле имя_модуля.service.yml, который лежит в корне нужного модуля (не обязательно самописного), мы должны объявить этот сервис (имя_модуля.lazy_renderer), который будет вызываться для формирования того, что надо вывести в переменную 'lazy_data', которая потом пойдёт в ту заглушку, в дом который построил Джек. В этом сервисе делаем функцию renderBigData, которая и будет вызываться. И вот эта функция должна вернуть ссылку на шаблон, который будет отрендерен и будет вставлен в нужное место страницы, в доме который построил Джек. Но в эту функцию хочется же передать что-нибудь, да? Вот как это делается. Во-первых, напоминаем, что для того, чтобы продать что-нибудь ненужное, надо сначала купить что-нибудь ненужное, а для того чтобы использовать шаблон для рендера, его надо сначала объявить. То есть — в файле имя_модуля.module, в функции function promotion_theme(...) надо вернуть, вместе с остальными заготовками шаблонов, заготовку нового шаблона: 'my_template_for_lazy_building' => [
'variables' => [ 'info' => '', 'params' => [], 'something_else' => 1 ], ], А дальше всё просто — в сервисе, в функции, подготавливается всё, что нужно, и этот свежеобъявленный шаблон возвращается на рендер, передав ему то, что тебе нужно ему передать. А у этого шаблона, в свою очередь, есть свой препроцессор, который сработает при попытке Drupal отрендерить шаблон. В этот момент препроцессор получит те переменные, которые объявлены и переданы. То есть, технически это выглядит так: // Смотрим выше на вызов сервиса из нашей переменной:
// 'имя_модуля.lazy_renderer:renderBigData' // и сопоставляем класс: class lazy_renderer { public function renderBigData($info, $params, $something_else) { //Обрати внимание на переменные функции //Что-то тут делаем, готовим данные. return [ '#theme' => 'my_template_for_lazy_building', '#info' => $info, '#params' => $params, '#something_else' => $something_else ]; } } Сам twig-шаблон должен лежать в каталоге template модуля, само собой. Вот и всё. И ещё раз, чтобы подытожить «кто на ком стоял»:
Надеемся, что смогли просто, но при этом максимально подробно, рассказать про технологию Lazy Builder. Спасибо за внимание. =========== Источник: habr.com =========== Похожие новости:
Разработка веб-сайтов ), #_php, #_drupal, #_programmirovanie ( Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:26
Часовой пояс: UTC + 5