PageSpeed OptiPic — автоматическая оптимизация сайта для требований Google Pagespeed Insights
JavaScript: Слияние, сжатие, ленивая загрузка. CSS: Сжатие размера и оптимизация загрузки. Оптимизация изображений. Оптимизация сторонних виджетов и систем аналитики.

Возможно ли отложить загрузку jQuery?

Давайте смиримся с этим, jQuery/jQuery-ui - тяжелая загрузка.

Google рекомендует отложенную загрузку JavaScript для ускорения начального рендеринга. На моей странице используется jQuery для настройки вкладок, которые находятся низко на странице (в основном за пределами начального просмотра), и я хотел бы отложить загрузку jQuery до завершения рендеринга страницы.

Код задержки Google добавляет тег в DOM после загрузки страницы, используя событие onLoad body:

<script type="text/javascript"> // Добавляем элемент скрипта в качестве потомка body function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "deferredfunctions.js"; document.body.appendChild(element); } // Проверяем поддержку браузера возможности обработки событий if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script> 

Я бы хотел отложить загрузку jQuery таким образом, но когда я попробовал это, мой код jQuery не смог найти jQuery (это было полностью предсказуемо с моей стороны):

$(document).ready(function() { $("#tabs").tabs(); }); 

Таким образом, кажется, что мне нужно найти способ отложить выполнение моего кода jQuery до загрузки jQuery. Как мне определить, что добавленный тег был загружен и проанализирован?

Кроме того, кажется, что асинхронная загрузка также может содержать ответ.

Какие у вас есть мысли?

#1

Попробуйте это, это то, что я отредактировал некоторое время назад с помощью закладки jQuerify. Я часто использую ее для загрузки jQuery и выполнения действий после его загрузки. Конечно, вы можете заменить там URL своим собственным URL вашего настроенного jquery.

(function() { function getScript(url,success){ var script=document.createElement('script'); script.src=url; var head=document.getElementsByTagName('head')[0], done=false; script.onload=script.onreadystatechange = function(){ if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) { done=true; success(); script.onload = script.onreadystatechange = null; head.removeChild(script); } }; head.appendChild(script); } getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',function(){ // Ваш код здесь и выполняется после загрузки jQuery }); })(); 

Я действительно соединяю jQuery и jQuery-UI в один файл и использую URL-адрес к нему. Если ВАМ ДЕЙСТВИТЕЛЬНО хочется загружать их отдельно, просто объедините getScripts:

getScript('http://myurltojquery.js',function(){ getScript('http://myurltojqueryUI.js',function(){ // ваш код вкладки здесь }) }); 
#2

Так как это вопрос топового рейтинга по важной теме, позвольте мне быть настолько смелым, чтобы представить свою точку зрения на основе предыдущего ответа от @valmarv и @amparsand.

Я использую многомерный массив для загрузки скриптов. Группируя те, которые не имеют зависимостей между ними:

var dfLoadStatus = 0; var dfLoadFiles = [ ["http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"], ["http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js", "/js/somespecial.js", "/js/feedback-widget.js#2312195", "/js/nohover.js"] ]; function downloadJSAtOnload() { if (!dfLoadFiles.length) return; var dfGroup = dfLoadFiles.shift(); dfLoadStatus = 0; for(var i = 0; i<dfGroup.length; i++) { dfLoadStatus++; var element = document.createElement('script'); element.src = dfGroup[i]; element.onload = element.onreadystatechange = function() { if ( ! this.readyState || this.readyState == 'complete') { dfLoadStatus--; if (dfLoadStatus==0) downloadJSAtOnload(); } }; document.body.appendChild(element); } } if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; 

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

dfLoadFiles.push(["/js/loadbeforeA.js"]); dfLoadFiles.push(["/js/javascriptA.js", "/js/javascriptB.js"]); dfLoadFiles.push(["/js/loadafterB.js"]); 
#3

Вот хорошее описание современного подхода к асинхронной/отложенной загрузке JavaScript. Но это не работает для встроенных скриптов.

<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script> <script type="text/javascript" defer> $(function () { // 

Простейшее решение для асинхронной загрузки было предложено @nilskp - внешние скрипты:

<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script> <script type="text/javascript" src="resources/js/onload.js" defer></script> 
#4

Я добавляю этот фрагмент кода после асинхронной/отложенной метки сценария jquery, это определяет временную функцию $, которая будет накапливать все то, что должно выполняться, когда все загрузится, и затем, когда мы закончим, использовать перезаписанную переменную $ для выполнения функций. С этим фрагментом кода нет необходимости изменять синтаксис onload jQuery дальше в документе.

<script defer async src="https://code.jquery.com/jquery-2.2.0.min.js"> <script> var executeLater = []; function $(func) { executeLater.push(func); } window.addEventListener('load', function () { $(function () { for (var c = 0; c 

....а затем...

<script> $(function() { alert("loaded"); }); </script> 
#5
element.addEventListener("load", function () { $('#tabs').tabs() }, false); 

Попробуйте это.

#6

Поместите jQuery и ваш код, зависящий от jQuery, в конец вашего HTML-файла.

Изменено: Более понятно

<html> <head></head> <body> <!-- Ваш обычный контент здесь --> <script type="text/javascript" src="http://путь/к/jquery/jquery.min.js"></script> <script>//Поместите свой код jQuery сюда</script> </body> </html> 
#7

В determiners ситуациях вы можете запустить событие, когда jquery загружен.

<скрипт type="текст / javascript">(function (window) { window.jQueryHasLoaded = false; document.body.addEventListener('jqueryloaded', function (e) { console.log('jqueryloaded ' + new Date()); }, false); function appendScript (script) { var tagS = document.createElement("script"), s = document.getElementsByTagName("script")[0]; tagS.src = script.src; s.parentNode.insertBefore(tagS, s); if (script.id == 'jquery') { tagS.addEventListener('load', function (e) { window.jQueryHasLoaded = true; var jQueryLoaded = new Event('jqueryloaded'); document.body.dispatchEvent(jQueryLoaded); }, false); } } var scripts = [{'id':'jquery','src':'js/libs/jquery/jquery-2.0.3.min.js'}, {'src': 'js/myscript1.js'}, {'src':'js/myscript2.js'}]; for (var i=0; i < scripts.length; i++) { appendScript(scripts[i]); } }(окно)); </script> 

Затем оберните ваши зависимости в функцию:

// myscript1.js (function () {function initMyjQueryDependency () { console.log('мой код выполняется после загрузки jquery!'); // здесь мой код, который зависит от jquery } if (jQueryHasLoaded === true) initMyjQueryDependency(); else document.body.addEventListener('jqueryloaded', initMyjQueryDependency, false); } ()); 

Если jquery заканчивает загружаться после других сценариев, ваши зависимости будут выполнены, когда будет сработано событие jqueryloaded.

Если jquery уже загружен, jQueryHasLoaded === true, ваша зависимость будет выполнена initMyjQueryDependency().

#8

Ну, кажется мне, все, что вам нужно сделать, это либо а) добавить код jQuery, который вы хотите запустить при загрузке, в конец файла jQuery, либо б) добавить его в функцию downloadJSAtOnload следующим образом:

<script type="text/javascript"> // Добавьте элемент script в качестве дочернего для body function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "deferredfunctions.js"; document.body.appendChild(element); $("#tabs").tabs(); // <==== ЗАМЕТЬТЕ. Это теоретически должно выполниться после того, // как скрипт был добавлен, хотя вы должны проверить это //, потому что я не знаю, будет ли JavaScript ждать // загрузки скрипта перед продолжением } // Проверьте поддержку браузера возможностей обработки событий if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script> 
#9

Следующий код должен загружать ваши скрипты после окончания загрузки окна:

<html> <head> <script> var jQueryLoaded = false; function test() { var myScript = document.createElement('script'); myScript.type = 'text/javascript'; myScript.async = true; myScript.src = jQueryLoaded ? 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js'; document.body.appendChild(myScript); if(!jQueryLoaded){ alert('jquery был загружен'); jQueryLoaded = true; test(); } else { alert('jqueryui был загружен'); } } if (window.addEventListener){ alert('window.addEventListener'); window.addEventListener("load", test, false); } else if (window.attachEvent){ alert('window.attachEvent'); window.attachEvent("onload", test); } else{ alert('window.onload'); window.onload = test; } </script> </head> <body> <p>Здесь размещается заполнитель текста</p> </body> </html> 

Работает для меня в Chrome, FF и IE9 - дайте мне знать, если это помогает

#10

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

var deferredJSFiles = ['jquery/jquery', 'file1', 'file2', 'file3']; function downloadJSAtOnload() { if (!deferredJSFiles.length) return; var deferredJSFile = deferredJSFiles.shift(); var element = document.createElement('script'); element.src = deferredJSFile.indexOf('http') == 0 ? deferredJSFile : '/js/' + deferredJSFile + '.js'; element.onload = element.onreadystatechange = function() { if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') downloadJSAtOnload(); }; document.body.appendChild(element); } if (window.addEventListener) window.addEventListener('load', downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent('onload', downloadJSAtOnload); else window.onload = downloadJSAtOnload; 
#11
<!doctype html> <html> <head> </head> <body> <p>Если вы нажмете на кнопку "Скрыть", я исчезну.</p> <button id="hide" >Скрыть</button> <button id="show" >Показать</button> <script type="text/javascript"> function loadScript(url, callback) { var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState) { //IE script.onreadystatechange = function() { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function() { callback(); }; } script.src = url; document.body.appendChild(script); } loadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", function() { //YAHOO.namespace("mystuff"); $("#show").click(function() { $("p").show(); }); $("#hide").click(function() { $("p").hide(); }); //more... }); </script> </body> </html> 
#12

Я считаю, что Modernizr.load() стоит упомянуть здесь - он очень хорошо обрабатывает загрузку зависимостей

#13

__XXXX__Применяется простой фокус, который использует Google Analytics. Подготовка

1. В верхней части вашего HTML-документа добавьте небольшой скрипт.

<script> window.jQuery_store = []; window.jQueryReady = function (fn) { jQuery_store.push(fn); } <\/script>  

Функция jQueryReady просто сохраняет делегаты в массив для будущего использования.

2. Создайте новый скрипт JS jquery-ready.js со следующим содержанием:

\/\/ Когда jQuery наконец готов $(function() { \/\/ Заменить предыдущую реализацию window.jQueryReady = function(fn) { \/\/ jQuery загружена вызываем fn() немедленно } \/\/ Вызвать все сохраненные обратные вызовы for (var i = 0; i  

Когда этот скрипт загружен, он:

  • Дожидается, пока можно использовать jQuery
  • Заменяем функцию jQueryReady на новую, которая просто немедленно вызывает делегата (jQuery готов в заданное время).
  • Перебирает функции, сохраненные из предыдущих вызовов jQueryReady.

    3. Соедините все вместе Создайте jquery-ready.js, чтобы он загружался только после загрузки jQuery. В вашем подвале должно быть:

    <script defer src="...\/jquery.min.js"> <script defer src="...\/bootstrap.min.js"> ... все остальные плагины для jQuery, которые вам, вероятно, понадобятся <script defer src="...\/jquery-ready.js">  

    Таким образом, скрипт jquery-ready.js будет выполняться только после выполнения jQuery. Использование

    Теперь вы можете использовать функцию jQueryReady в любое время.

    jQueryReady(function() { \/\/ jQuery можно использовать здесь $("div.to-be-hidden").hide(); }) 
                        

#14

Похоже, что вам просто нужно использовать <script defer> : http://www.w3schools.com/tags/att_script_defer.asp

#15

Ознакомьтесь с jQuery.holdReady()

"Блокирует или разрешает выполнение события готовности jQuery." (jQuery 1.6+)

http://api.jquery.com/jQuery.holdReady/

#16

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

Мой быстрый код может не работать со всеми функциями jQuery, но до сих пор все работало, кроме одного вызова функции, который я пробовал. Обычно я делаю такие настраиваемые вещи недоступными, но я решил разместить этот фрагмент онлайн. Доступен здесь https://github.com/andrewtranter/jQuery_deferred_compat

#17

Загружайте все скрипты в конце HTML с помощью http://labjs.com, это 100% решение, которое я много раз тестировал по правилам gtmetrix. Пример: http://gtmetrix.com/reports/interactio.cz/jxomHSLV

?