Ленивая загрузка комментариев Disqus

Ленивая загрузка комментариев Disqus

От автора: в продуманных макетах комментарии, как правило, играют второстепенную роль. Во множестве случаев посетители так и не долистывают страницу до комментариев. Но я вам открою глаза, по умолчанию комментарии загружаются на сайт, что может вызвать проблемы на плохом соединении.

Давайте разберем код вставки от Disqus:

<div id="disqus_thread"></div>
<script>
  (function() {
    var d = document, s = d.createElement('script');
    s.src = '//username.disqus.com/embed.js';
    s.setAttribute('data-timestamp', +new Date());
    (d.head || d.body).appendChild(s);
  })();
</script>

Они говорят: «Вставьте следующий код в том месте, где хотите поместить комментарии Disqus». Предположим, что вы хороший разработчик и подключаете все скрипты <script src=»…»></script> перед закрывающим тегом body. В один прекрасный день вы захотели подключить Disqus комментарии на свой сайт и вставили код выше где-то в середине документа в том месте, где должен располагаться блок комментариев.

Что тогда произойдет? Тогда первым JS файлом, который начнет загружаться, станет username.disqus.com/embed.js. Не факт, что он загрузится первым, но он первый из линейки JS файлов, который привлечет внимание браузера. Не стоит ли первое место отвести под главный JS файл сайта? Если главный JS файл загрузится не вовремя, много чего может пойти не так (например, «спящие» button и т.д.). Особенно если во время разработки вы не придерживались техник прогрессивного улучшения или изящной деградации.

Это также влияет на работу других внешних файлов, таких как изображения и CSS файлы. Представьте, вы на смартфоне с 2G соединением ждете, когда загрузится виджет комментариев, чтобы посмотреть фото котенка.

Я провел тестирование и выяснил, что виджет Disqus без самих комментариев весит 2.49 Мб! Это куча запросов JS, CSS, изображений и файлов шрифтов, которые во многих случаях сильно замедляют работу других, более критичных частей или функционал вашего сайта.

Ленивая загрузка комментариев Disqus

Комментарии Disqus: без ленивой загрузки

Решение: крошечный JavaScript плагин

Для ленивой загрузки комментариев Disqus я написал крошечный JS плагин. Неважно где располагается зона комментариев, выше или ниже области просмотра, она не подгрузится, пока на это не появится причина:

Ленивая загрузка комментариев Disqus

Комментарии Disqus: с ленивой загрузкой

Сам плагин представляет собой буквально пару строк JS. Я сделал две версии: на чистом JS и на JQuery. Плагин называется disqusLoader, можете скачать файлы:

disqusloader.js; независимый (IE 9+). 779 байт в минифицированном и сжатом виде.

jquery.disqusloader.js; нужен jQuery. 569 байт в минифицированном и сжатом виде.

Как его установить. Сперва необходимо вставить в HTML тег в том месте, где должна быть область комментариев:

<div class="disqus"></div>

После необходимо инициализировать плагин, вот так:

// обычный JS
disqusLoader( '.disqus', { scriptUrl: '//username.disqus.com/embed.js' });

// jQuery
$.disqusLoader( '.disqus', { scriptUrl: '//username.disqus.com/embed.js' });

«Ну ладно, а что делать с настройками Disqus» — спросите вы. Есть еще один аргумент, который принимает значение Disqus. Также есть еще парочка опций в плагине:

var options =
{
  scriptUrl: '//username.disqus.com/embed.js',
  /*
    @type: string (url)
    @default: none
    @required
    URL исполняемого JS файла Disqus. Значение запоминается при первом вызове функции и далее игнорируется, так как Disqus разрешает только один экземпляр на странице.
.
  */

  laziness: 1,
  /*
    @type: int (>=0)
    @default: 1
    Устанавливает степень ленивой загрузки виджета: (viewport height) * laziness . К примеру:
    0 – виджет начинает загружаться, как только малейшая его часть попала в область просмотра;
    1 – виджет начинает загружаться, когда расстояние от виджета до границы области просмотра меньше высоты области просмотра;
    2 - 2x от области просмотра и т.д.
  */

  throttle: 250,
  /*
    @type: int (milliseconds)
    @default: 250
    Задает частоту вычислений, который будет проводить плагин во время различных процессов, таких как изменение размера окна браузера или прокрутка экрана
.
    250 = 4 times in a second.
  */

  /*
    @type: function
    @default: none
    Родная опция Disqus. Более подробно смотрите в руководстве к Disqus.
  */
  disqusConfig: function()
  {
    this.page.title       = 'Page Title';
    this.page.url         = 'http://url.to/your-website';
    this.page.identifier  = 'unique-identifier';
  }
};

// обычный JS
disqusLoader( '.disqus', options );

// jQuery
$.disqusLoader( '.disqus', options );

Попробуйте плагин сами, посмотрите демо. Можете присоединиться к проекту или следить за ним на GitHub.

Колбэк-функции Disqus

Колбэк-функции – отличная штука, с их помощью можно реагировать на действия пользователя. В Disqus есть всего один вид официально задокументированных колбэк-функций. Если же открыть код файла embed.js, можно найти дополнительные виды предопределенных колбэк-функций:

Ленивая загрузка комментариев Disqus

Комментарии Disqus: список колбэк-функций в исходном коде embed.js

Похоже, что только два вида активны: onNewComment и onReady. Этого вполне достаточно для небольшого, но заметного улучшения – индикатора загрузки.

Индикатор загрузки

Обычно загрузка виджета Disqus состоит из двух частей:

загрузка файла `embed.js`;

загрузка внутренних файлов и выполнение запросов другого типа.

Disqus сам заботится о втором этапе, показывая анимированное изображение загрузки. А первый этап? Существует масса причин, почему загрузка внешних JS файлов может занимать десятки секунд. Подвох в том, что независимо от сети, в которой находится пользователь, он будет знать, что на вашем сайте предусмотрена функция комментариев. Пользовательский опыт кроется в деталях!

Ленивая загрузка комментариев Disqus

Комментарии Disqus: индикатор загрузки

Техническая часть простая: новый HTML тег и JS колбэк-функция, которая будет его прятать:

<div class="disqus-placeholder">Loading comments...</div>
<div class="disqus"></div>
// обычный JS
disqusConfig: function()
{
  this.callbacks.onReady = [function()
  {
    var el = document.querySelector( '.disqus-placeholder' );
    if( el.classList )
      el.classList.add( 'is-hidden' ); // IE 10+
    else
      el.className += ' ' + 'is-hidden'; // IE 8-9
  }];
}

// jQuery
disqusConfig: function()
{
  this.callbacks.onReady = [function()
  {
    $( '.disqus-placeholder' ).addClass( 'is-hidden' );
  }];
}
.disqus-placeholder.is-hidden { display: none; }

На странице демо можно посмотреть все это в действии. Но сперва почистите кэш браузера и замедлите скорость соединения.

Несколько экземпляров или сайтов за раз?

Работая над этой техникой, я обнаружил пару серьезных ограничений, которые есть на данный момент…

Невозможно иметь несколько скриптов на одной странице

После загрузки скрипта (например, //username.disqus.com/embed.js) создается глобальная переменная window.DISQUS, но только в том случае, если она не была объявлена ранее (плохой знак). Я провел тестирование. Я инициализировал виджет в исходнике А. Затем освободил место под будущую переменную window.DISQUS = undefined и инициализировал видежт в исходнике В. Результат был удручающий: колбэк-функции запускались по несколько раз, комментарии дублировались и т.д. Очевидно, что текущий код Disqus не поддерживает несколько переменных и не создан для раздельной работы с экземплярами виджета.

Невозможно поместить на одну страницу несколько виджетов

В объекте DISUQS есть публичный JS метод reset(). Если вы работали с Disqus, то должны знать, что виджет вставляется в тег с идентификатором disqus_thread. Я протестировал виджет с двумя тегами: загрузил виджет в первый тег, удалил ID атрибут и вставил виджет во второй элемент. После я вызвал функцию reset, ожидая, что появится второй экземпляр ниже первого. Однако вызов функции на загрузку нового экземпляра уничтожает все предыдущие инициализированные виджеты. К сожалению, на данный момент Disqus спроектирован для вставки одного экземпляра.

Виджет можно перезагружать в реальном времени

Но есть и плюсы! Нельзя иметь несколько экземпляров виджета за один раз, однако вы можете уничтожить старые экземпляры и загрузить новые. Переведем теорию в практику в самой типичной ситуации – вкладки. Нужно лишь вызывать плагин каждый раз, когда активируется новая вкладка:

<div class="tabcontent" data-disqus-id="venus" data-disqus-title="Venus"></div>
<div class="tabcontent" data-disqus-id="earth" data-disqus-title="Earth"></div>
<div class="tabcontent" data-disqus-id="mars" data-disqus-title="Mars"></div>
// вызывайте эту функцию при каждом клике на вкладку:

var initDisqus = function( content )
{
  disqusLoader( content,
  {
    scriptUrl:    '//username.disqus.com/embed.js',
    disqusConfig: function()
    {
      this.page.identifier  = content.getAttribute( 'data-disqus-id' );
      this.page.title     = content.getAttribute( 'data-disqus-title' );
    }
  });
}

На странице демо можно посмотреть код в действии, а также посмотреть весь код.

Заключительные мысли

Этот пост не о недостатках Disqus. Он об ошибках, которые мы, разработчики совершаем. В нашем мире полно инструментов, и только от нас зависит, как мы ими воспользуемся. Даже если эти инструменты решают какие-то конкретные проблемы, они могут принести новые, если неправильно их использовать. Каждый раз, когда вы выбираете простой путь, вы теряете пользователей, падает конверсия, а процент отказа увеличивается. Уже сейчас можно использовать ленивую загрузку для Disqus, Google Adsense, Google Maps, кнопок социальных сетей, а также можно разработать и поделиться собственными техниками. Будьте ответственными разработчиками!

Автор: Osvaldas Valutis

Источник: https://css-tricks.com/

Редакция: Команда webformyself.

Самые свежие новости IT и веб-разработки на нашем Telegram-канале

JavaScript&jQuery с нуля до профи

Пройдите пошаговый видеокурс по JavaScript&jQuery

Научиться

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree