Ленивая загрузка скрипта addthis? (или ленивая загрузка внешнего содержимого js, зависящего от уже запущенных событий)

Я хочу, чтобы виджет addthis был доступен для моих пользователей, но я хочу лениво загружать его, чтобы загружалась моя страница как можно быстрее. Однако, попробовав его с помощью тега script, а затем с помощью моего метода ленивой загрузки, похоже, он работает только через тег script. В запутанном коде я вижу нечто, похожее на то, что оно зависит от события DOMContentLoaded (по крайней мере, для Firefox).

Поскольку событие DOMContentLoaded уже запущено, виджет не отображается должным образом. Что делать?

Я мог бы просто использовать тег script (медленнее)... или я мог бы запустить (в кросс-браузерном режиме) событие DOMContentLoaded (или эквивалентное)? У меня есть ощущение, что это может быть невозможно, потому что я считаю, что (как и jQuery) существует несколько тестов события готовности контента, и поэтому должно произойти несколько смоделированных событий.

Тем не менее, это интересная проблема, потому что я видел пару виджетов, которые теперь предполагают, что вы включаете их содержимое через статические теги скрипта. Было бы неплохо, если бы они написали код, который был бы более полезен для разработчиков, заботящихся о скорости, но до тех пор есть ли обходной путь? И/или какие-то из моих предположений неверны?

Редактировать: Поскольку первый ответ на вопрос, похоже, упускал суть моей проблемы, я хотел прояснить ситуацию.

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

  1. внешние виджеты, над которыми у вас нет контроля и которые могут быть или не быть запутанными
  2. задержка загрузки внешних виджетов до тех пор, пока они не потребуются, или, по крайней мере, до тех пор, пока не будет загружено все остальное, включая другие отложенные элементы
  3. b/c того, как был написан виджет, исключает существующие, типичные парадигмы ленивой загрузки

Хотя это эзотерика, я видел, как это произошло с парой виджетов, где разработчики виджетов предполагают, что вы просто хотите добавить еще один тег сценария внизу страницы. Я хочу сэкономить эти 500-1000 мс**, поскольку многочисленные исследования Yahoo, Google и Amazon показывают, что это важно для вашего пользовательского опыта.

**Мой тест с головкой-молотом и личный опыт показывают, что в данном случае это будет моя экономия.


person Keith Bentrup    schedule 03.06.2009    source источник


Ответы (4)


Самое простое решение — установить для параметра domready значение 1 при внедрении скрипта addthis на вашу страницу. Вот пример:

<script type="text/javascript" 
src="http://s7.addthis.com/js/250/addthis_widget.js#username=addthis&domready=1">
</script>

Я протестировал его в IE, Firefox, Chrome и Safari, и все работало нормально. Дополнительную информацию о параметрах конфигурации addthis можно найти здесь.

person Hamid    schedule 15.06.2010
comment
Этот пост в блоге был очень полезен t.co/6uk9sHU0. По сути, после того, как вы загрузите свой контент через ajax, вы загружаете скрипт addthis через $.getScript, а затем вызываете addthis.init() после завершения загрузки скрипта. - person SomethingOn; 13.12.2011
comment
прямо сейчас есть также опция async, которая делает загрузку страницы еще быстрее. addthis.com/help/optimizing-addthis - person dragoon; 30.01.2012

Этот код решает проблему и экономит время загрузки, которое я искал.

Прочитав этот сообщение о том, как большинство современных библиотек js реализуют тесты для события, загруженного домом. Я провел некоторое время с запутанным кодом и смог определить, что addthis использует комбинацию упомянутого метода doscroll, таймеров и события DOMContentLoaded для различных браузеров. Поскольку только тем браузерам, которые зависят от события DOMContentloaded, в любом случае потребуется следующий код:

if( document.createEvent ) {
 var evt = document.createEvent("MutationEvents"); 
 evt.initMutationEvent("DOMContentLoaded", true, true, document, "", "", "", 0); 
 document.dispatchEvent(evt);
}

а остальные зависят от таймеров, проверяющих наличие определенных свойств, мне нужно было только приспособить этот случай, чтобы иметь возможность лениво загружать этот внешний JS-контент, а не использовать статические теги скрипта, тем самым экономя время, на которое я надеялся. :)

person Keith Bentrup    schedule 03.06.2009

Редактировать: если цель состоит в том, чтобы сначала загрузить другой контент, попробуйте поместить теги <script> в нижней части страницы. Он по-прежнему сможет перехватывать DOMContentLoaded, а предшествующий контент будет загружаться перед сценарием.

Оригинал:

в дополнение к загрузке DOMContentLoaded, вы можете загрузить его, если для определенного var установлено значение true. например

var isDOMContentLoaded = false;

document.addEventListener("DOMContentLoaded",function() { isDOMContentLoaded = true; }, false);

затем добавьте в другой файл сценария

if (isDOMContentLoaded) loadThisScript();

Изменить в ответ на комментарии:

Загрузите сценарий и запустите функцию, которую запускает прослушиватель DOMContentLoaded. (прочитайте сценарий, если вы не уверены, какая функция вызывается).

e.g.

var timerID;
var iteration=0;

function checkAndLoad() {
    if (typeof loadThisScript != "undefined") {
        clearInterval(timerID);
        loadThisScript();
    }
    iteration++;
    if (iteration > 59) clearInterval(timerID);
}

var extScript = document.createElement("script");
extScript.setAttribute("src",scriptSrcHere);
document.head.appendChild(extScript);

timerID = setInterval(checkAndLoad,1000);

Вышеописанное будет пытаться раз в секунду в течение 60 секунд проверять, доступна ли нужная вам функция, и, если да, запускать ее

person Jonathan Fingland    schedule 03.06.2009
comment
Это внешний виджет js. Я не контролирую содержание. - person Keith Bentrup; 03.06.2009
comment
Есть пара разделов, которые относятся к событию DOMContentLoaded, которые вызывают анонимные функции и, похоже, находятся в закрытии со скрытым состоянием. Это запутанный код, поэтому, хотя я пытаюсь выяснить, что именно они делают с событием DOMContentLoaded, это может быть не так просто. Я рассматриваю другой подход - пытаюсь выяснить, какие события он ищет и запускает, и мне интересно, может ли быть обобщенное решение - некоторый код для запуска события DOMContentLoaded после того, как реальный браузер уже уволен или каким-либо другим способом вызвать его. - person Keith Bentrup; 03.06.2009
comment
удалите анонимные функции и дайте им имя в вашем скрипте. var loadFunction = function() { /* what*/ } затем вызовите эти функции из функции checkAndLoad() - person Jonathan Fingland; 03.06.2009
comment
Как мне убрать анонимные функции? У меня нет контроля над внешним js. - person Keith Bentrup; 03.06.2009
comment
насколько мне известно, нет никакого способа запустить DOMContentLoaded после того, как страница уже запустила его один раз. Есть что-то подобное для jquery для имитации событий мыши и клавиатуры, но я ничего не знаю о DOMcontentLoaded. - person Jonathan Fingland; 03.06.2009
comment
скачайте js и скопируйте/вставьте - person Jonathan Fingland; 03.06.2009
comment
Но в этой функции указано, что я не могу просто вырезать и вставить этот раздел. Мне нужно было бы понять, в каком состоянии находятся различные переменные в момент их вызова, поэтому мне приходится тратить больше времени на разбор запутанного кода. Возможно, в конечном итоге мне придется сделать это, если нет обходного пути, но я надеюсь, что другой подход может быть более плодотворным. - person Keith Bentrup; 03.06.2009
comment
вы можете рассмотреть это дополнение Firefox addons.mozilla.org/en-US/ firefox/addon/10345 Это должно помочь вам проанализировать, что делает скрипт - person Jonathan Fingland; 03.06.2009
comment
спасибо за ссылку на дополнение. я с нетерпением жду возможности протестировать его. - person Keith Bentrup; 03.06.2009

В AddThis есть раздел о том, как асинхронно загружать свои инструменты.

Текущее «лучшее» решение:

<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=[YOUR PROFILE ID]" async="async"></script>
person MastaBaba    schedule 10.07.2019