Блоги Отложенная загрузка и быстрый просмотр товара

Все то же самое, что на видео, только текстом:

Привет! Пока у нас готовиться целый пул дополнений в аддонсы, давайте я расскажу Вам про defer. Я заметила, что вы его уже знаете и даже применяете в своей работе. Это здорово! Освежу информацию.

defer — атрибут шаблонного тега. Любого — нашего, вашего, общего, модульного. Его можно использовать даже там, где нет к этому указаний в документации.

У него можно задать три значения:

  • event — событие
  • emergence — появление
  • async — асинхронная загрузка
  • sync — последовательная загрузка.

Сразу попробуем. На странице «О компании» выведем блок товаров. Добавим атрибут defer=event.

<insert name="show_block" module="shop" defer="event">

Блок будет загружаться только по событию — клик по кнопке «Загрузить».

Можно добавить атрибут defer_title — альтернативный текст.

<insert name="show_block" module="shop" defer="event" defer_title="Если вы не видите товары, нажмите ">

Вот он и появился.

Теперь зададим emergence для атрибута defer. Значение загрузилось сразу.

<insert name="show_block" module="shop" defer="emergence">

Атрибут предполагает, что значение будет загружено при попадании блока на экран пользователя. Давайте выведем сначала текст. Обновим страницу. Она загрузилась. А теперь смотрите. Я прокручиваю сайт вниз. Видели? Только когда мы докрутили до блока, он начал загружаться.

Остальные два значения загружают тег сразу после того как страница сформировалась. Здесь разница в том как они будут загружены относительно друг друга. Давайте 3 тега выведем. Я поменяю тег на корзину. Он компактнее и для нас нагляднее. defer зададим как sync.

<insert name="show_block" module="cart" defer="sync">
<insert name="show_block" module="cart" defer="sync">
<insert name="show_block" module="cart" defer="sync">

Так. Успели заметить? Я специально замедлила видео. Теги грузились один за другим.

Поменяю на async — одновременная загрузка.

<insert name="show_block" module="cart" defer="async">
<insert name="show_block" module="cart" defer="async">
<insert name="show_block" module="cart" defer="async">

Ну-ка. Действительно одновременная.

А теперь кейсы. Как мы его можем использовать для других задач? Что такого делает атрибут? Подгружает содержимое тега. То есть это Ajax запрос без необходимости прописывать что-то в PHP-коде. Прописываете определённый код в вёрстке или в JS. И подгружаете любой тег.

Обычно нам нужно подгружать данные в pop-up: быстрый просмотр товара, форма обратного звонка, форма авторизации. Всё, что пользователь сразу не видит, давайте не будем выводить. Это облегчит страницу, мы быстрее её отдадим, Google будет счастлив, пользователь будет счастлив, владелец сайта будет доволен.

Показываю.

Сделаем предпросмотр товара.

Открываем шаблон списка товара modules/shop/views/shop.view.rows.php и для каждого товара выводим блок, который показывает один товар. Загрузка по событию.

foreach ($result['rows'] as $row)
{        
    echo '<div class="js_shop shop-item shop">';
    echo $this->htmleditor('<insert name="show_block" module="shop" ids="'.$row["id"].'" defer="event">');

Вот у нас выведена кнопка «Загрузить». Кликаем на неё и товар загружается. Осталось только красиво оформить.

Перенесём тег под изображения. Зададим свой шаблон атрибутом template.

echo $this->htmleditor('<insert name="show_block" module="shop" ids="'.$row["id"].'" defer="event" template="preview">');

Вот этот шаблон. Я заранее его подготовила — скопировала туда код из шаблона карточки товара. Скачать шаблон можно по ссылке.

Давайте сделаем кнопку быстрого просмотра. Зададим класс, чтобы поставить кнопку на обработку. Укажем, что клик по кнопке перейдет в модуль fancybox и он откроет блок с заданным идентификатором.

echo '<input type="button" value="Быстрый просмотр" class="js_preview_button" data-fancybox data-src="#js_preview_block_'.$row["id"].'">';

Теперь создаём этот блок. Внутри укажем наш шаблонный тег. Укажем класс для JS. Еще для тега укажем, что товарам нужны изображения. 50 штук достаточно. И скроем блок с кнопкой «Загрузить».

echo '<div class="js_preview_block" id="js_preview_block_'.$row["id"].'" style="display:none">'.$this->htmleditor('<insert name="show_block" module="shop" ids="'.$row["id"].'" defer="event" template="preview" images="50">').'</div>';

Осталась только JS-обработка. Создадим файл modules/shop/js/shop.rows.js. Он подключится автоматом к шаблону shop.view.rows.php.

Здесь укажем, что при клике на кнопку сабмитим форму с кнопкой «Загрузить». У формы отложенной загрузки всегда есть класс js_НАЗВАНИЕМОДУЛЯ_НАЗВАНИЕТЕГА. И уточним, что эта форма из одного контейнера с нашей кнопкой.

$('.js_preview_button').click(function(){
   $('.js_shop_show_block', $(this).parents('.js_shop')).submit(); 
});

Проверяем.

Великолепно!

Я знаю, что вы все такие умельцы. Наверняка кто-то придумал хитрющий способ использовать defer. Поделитесь, пожалуйста, в комментариях. А я вам поставлю сердечко за это image

Комментарии

14 августаМакс (Maks): Спасибо большое за такой подробный и понятный урок!
Мне вы очень сильно помогли!

Побольше бы таких уроков
15 августаМарина Дорохина (summer): Рада стараться. Побольше - будет
15 августаАлександр (capitan): А если для поисковиков вообще отдавать только страницу с текстом, а оформление загружать отложенной загрузкой? Как они на это отреагируют?
15 августаВиталий (diafan1):
Цитата
А если для поисковиков вообще отдавать только страницу с текстом, а оформление загружать отложенной загрузкой? Как они на это отреагируют?
Хорошо отреагируют, положительно. Я на многих сайтах как минимум всякие блоки с телефонами, подвалами, боковыми колонками, фильтрами и пр. в defer убираю. Поисковики видят уникальный чистый короткий контент, а пользователи большой сайт. Всё довольны
15 августаАндрей (R4W): Активно использую при ананизме с Google PageSpeed Insights - жаль только параметр "время выполнения JS" увеличивает

С быстрым просмотром это Вы прикольно придумали :) Я обычно для этого открывал iframe в fancybox по ссылке ?quckview например, а в модельке делал условие при наличии quckview меняем тему сайта и шаблон сайта на специализированные. Приходилось правда JS ядра чуть менять чтобы скажем корзинка обновлялась во внешнем window
19 августаПавел (kpv77725): Вопрос:
Есть два блока show_block модуля shop. Например один с акцей, другой с новинками. У них отложенная загрузка emergence. Если к ним подключён shop.buy_form.js, то он сработает каждый раз при отложенной загрузке. Но если я подключу shop.buy_form_form.js то он сработает только 1 раз, во время первой загрузки . Почему?
19 августаМарина Дорохина (summer): Павел, в JS-файле есть функция инициализации файла, если он уже загружен на странице. Эта функция использует в своем названии название файла. У Вас она, видимо, просто не правильно названа. Скопировали shop.buy_form.js в shop.buy_form_form.js, а функцию инициализации не переименовали. Должно быть так:


Код
function init_shop_buy_form_form() {
...
}

$(document).ready(function() {
init_shop_buy_form_from();
});
19 августаПавел (kpv77725): Понял, спасибо :)