Асинхронная загрузка при наличии inline JavaScript

Часто при ускорении загрузки сайта не получается сделать асинхронной загрузку тяжелых библиотек вроде jQuery из-за того, что зависимый от них код вставлен прямо в HTML-страницу с помощью тега script (так называемый inline JavaScript), а вынести его в отдельный файл и использовать HeadJS по каким-либо причинам нет возможности. Чаще всего такое встречается, когда JavaScript генерируется CMS. Но недавно я узнал, как можно сделать загрузку асинхронной и в этом случае: через пользовательские события (custom events). Делается это так: существующий inline-код оборачиваем функцией-обработчиком события с выбранным нами именем, например jQeuryLoaded:



<script type="text/javascript">
 document.addEventListener('jQueryLoaded',function(e) {
  // сюда попадает inline-код, зависящий от jQuery, например:
  //  jQuery('p').css('color','#00dd00');
 });
</script>
А затем делаем асинхронную загрузку jQuery через JavaScript с последующим срабатыванием этого события:

<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.