Асинхронная загрузка при наличии inline JavaScript
Часто при ускорении загрузки сайта не получается сделать асинхронной загрузку тяжелых библиотек вроде jQuery из-за того, что зависимый от них код вставлен прямо в HTML-страницу с помощью тега script (так называемый inline JavaScript), а вынести его в отдельный файл и использовать HeadJS по каким-либо причинам нет возможности. Чаще всего такое встречается, когда JavaScript генерируется CMS. Но недавно я узнал, как можно сделать загрузку асинхронной и в этом случае: через пользовательские события (custom events). Делается это так: существующий inline-код оборачиваем функцией-обработчиком события с выбранным нами именем, например jQeuryLoaded:
А затем делаем асинхронную загрузку jQuery через JavaScript с последующим срабатыванием этого события:
<script type="text/javascript">
document.addEventListener('jQueryLoaded',function(e) {
// сюда попадает inline-код, зависящий от jQuery, например:
// jQuery('p').css('color','#00dd00');
});
</script>
<script type="text/javascript">
(function (d) {
var e=d.createElement('script');
e.async=true;
e.src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
e.type="text/javascript";
e.onload=function() {
// вот здесь при корректной загрузке JQuery вызывается обработчик, запускающий все inline-скрипты
d.dispatchEvent(new CustomEvent("jQueryLoaded"));
}
d.getElementsByTagName('head')[0].appendChild(e);
})(document);
</sctipt>
Если у нас всего одна библиотека, от которой зависит inline-код, можно попробовать и более простой вариант:
<script type="text/javascript" async="async" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" onload="document.dispatchEvent(new CustomEvent('jQueryLoaded'));" ></script>
Также можно совместить такую загрузку с использованием HeadJS. В этом случае вызов dispatchEvent нужно делать из функции, которая передается в качестве параметра функции load.
Примечание: такой способ вызова события не работает в старых версиях IE.