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

Посмотрим правде в глаза, jQuery / jQuery-ui - это тяжелая загрузка.

Google рекомендует отложенную загрузку JavaScript для ускорения первоначального рендеринга. . Моя страница использует jQuery для настройки некоторых вкладок, которые размещаются низко на странице (в основном вне начального представления), и я хотел бы отложить jQuery до ПОСЛЕ отображения страницы.

Код отсрочки Google добавляет тег в DOM после загрузки страницы путем подключения к событию onLoad тела:

<script type="text/javascript">

 // Add a script element as a child of the body
 function downloadJSAtOnload() {
 var element = document.createElement("script");
 element.src = "deferredfunctions.js";
 document.body.appendChild(element);
 }

 // Check for browser support of event handling capability
 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. Как определить, что добавленный тег завершил загрузку и анализ?

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

Есть предположения?


person Kevin P. Rice    schedule 02.05.2011    source источник
comment
Почему бы просто не включить jQuery (и ваши собственные файлы JS) внизу страницы, а не в голове?   -  person Kevin Ennis    schedule 02.05.2011
comment
Google говорит (в первой предоставленной мной ссылке) скрипты должны быть загружены, проанализированы и выполнены, прежде чем браузер сможет начать отображать веб-страницу. Это означает, что загрузка jQuery внизу страницы означает, что страница все еще не отображается до тех пор, пока jQuery не будет проанализирован и запущен. Есть ли способ загрузить его асинхронно и позволить ему выполнять свою работу после загрузки страницы?   -  person Kevin P. Rice    schedule 02.05.2011
comment
Разве вы не можете defer все свои внешние скрипты? Они должны по-прежнему выполняться в указанном порядке.   -  person nilskp    schedule 14.10.2012
comment
@nilskp Похоже, что для этого вопроса существовала бы существующая и принятая передовая практика, поэтому я представил ее, а не пытался изменить свою. В этой области есть множество подводных камней со всеми различными браузерами.   -  person Kevin P. Rice    schedule 14.10.2012
comment
Если вы отложите все скрипты, они будут (или, по крайней мере, должны) загружаться в одном и том же порядке, просто загружаются, когда браузер сочтет это оптимальным. async, однако, позволит загружать файлы js в любом порядке, который браузер сочтет нужным. Поэтому у вас не должно возникнуть проблем, если вы отложите все файлы скриптов, включая библиотеки JQuery.   -  person Phill Healey    schedule 23.08.2016
comment
Я когда-то async и jQuery, и свой скрипт. Мой скрипт проверил наличие window.jQuery. Если он не существует, он присоединит загрузчик к тегу jQuery. github2.com/toyojone   -  person johnchen902    schedule 08.10.2017


Ответы (15)


Попробуйте это, это я недавно редактировал в букмарклете 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(){
            // YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
        });
    })();

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

getScript('http://myurltojquery.js',function(){
        getScript('http://myurltojqueryUI.js',function(){
              //your tab code here
        })
});
person ampersand    schedule 02.05.2011
comment
Похоже на причудливую версию предложения Тайлермвашберна. Откладывая все, я думаю, это создает проблему порядка зависимостей: MyCode полагается на JQueryUI полагается на JQuery. Таким образом, необходим некоторый код для загрузки каждого из них в правильном порядке. Вы дали мне несколько идей. - person Kevin P. Rice; 02.05.2011
comment
на самом деле, это полностью отличается от предложения Тайлермвашберна. Это для вас загружает jQuery, а затем загружает jQuery ui, и THEN выполняет ваш jquery / jqueryUI-зависимый код, который вы просили ... этот код кроссбраузерный (поэтому он выглядит `` причудливо '') и у меня работает каждый раз. Что касается кода DOMready, я просто понял, что он может быть немного староват, и я бы его не использовал. Я думаю, что у меня где-то есть обновленное domready ... позвольте мне его найти. - person ampersand; 02.05.2011
comment
Предложение Тайлера хорошее. Что бы я сделал, так это сделать связанные сценарии get-скриптов обратным вызовом события загрузки тела. - person ampersand; 02.05.2011
comment
Да, я вижу различия, но он точно так же ждет события onload / onreadystatechange. ТАКЖЕ: я не думаю, что DOMready необходим, поскольку jQuery предоставляет его, верно? Пока зависимости удовлетворяются путем загрузки скриптов по порядку, я предполагаю, что метод jQuery .ready () задержит выполнение в том случае, если все скрипты загружены до того, как произойдет DOMready. - person Kevin P. Rice; 02.05.2011
comment
то, что я пытался с битом DOMready, должно было предоставить решение для этой части вашего вопроса: ... отложить jQuery до ПОСЛЕ отображения страницы. Если вы хотите отложить эти getScripts () до тех пор, пока страница не будет отрисована, вам нужно СНАЧАЛА иметь альтернативу domready, потому что вы не можете использовать jQuery ... потому что вы загружаете jQuery ПОСЛЕ. Во всяком случае, я считаю, что для ваших целей это не нужно. Если вы привяжетесь к событию загрузки body, я думаю, вы получите то, что ищете. - person ampersand; 02.05.2011
comment
@ampersand, На самом деле метод jQuery .ready () будет доступен - позвольте мне объяснить ... Я только пытаюсь загрузить отложенные / асинхронные сценарии, чтобы браузер не задерживал отображение страницы и взаимодействие с пользователем; однако я не обязательно пытаюсь обеспечить DOMready перед загрузкой jQuery (хотя я думаю, что загрузка тела может быть почти эквивалентом). Мне просто нужно убедиться, что все скрипты загружаются в правильном порядке - и если это произойдет, метод jQuery .ready () будет доступен, поскольку он загружается первым! Возможно, мне следует искать событие раньше, чем загрузка тела (которая может быть DOMready)? Курица или яйцо ... - person Kevin P. Rice; 02.05.2011
comment
Я использовал это с большим успехом. Я также изменил success(); в строке 10 на if(success && getClass.call(success) == '[object Function]') { success(); }. Это выполняет функцию успеха только, если она не равна нулю и является функцией. Это позволяет вам просто вызывать getScript("myScript.js") без вызова функции. - person Dan Atkinson; 27.03.2013
comment
@DanAtkinson разве не должно быть в вашем коде getScript вместо getClass? Можем ли мы использовать сценарий для откладывания нескольких файлов Js (не только JQuery), должны ли они быть зависимыми. - person Geniusknight; 24.07.2014
comment
@Geniusknight Да, это getScript ()! :) Его можно использовать для отсрочки более чем одной, и если есть зависимости, вам нужно будет кодировать для них, чтобы гарантировать, что они загружены, прежде чем вы попытаетесь запустить какие-либо дочерние скрипты, которые зависят от этого. Использование многомерного массива было бы довольно простым способом сделать это. - person Dan Atkinson; 25.07.2014
comment
Большой! Теперь я могу сдвинуть дело с мертвой точки. хе-хе: D Хорошего дня! - person Geniusknight; 25.07.2014
comment
Простой вопрос ... когда мы вызываем такие скрипты, браузер все равно будет использовать кеш? - person Paulo Lima; 10.09.2019

Поскольку это вопрос наивысшего рейтинга по важной теме, позвольте мне проявить смелость, чтобы высказать свое мнение по этому поводу, основанное на предыдущем ответе от @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"]);
person Pevawi    schedule 23.08.2013
comment
Это все еще необходимо для атрибутов async и / или defer в тегах ‹script›? см. mediaevent.de/javascript/programm-struktur.html (извините, это на немецкий язык, вы можете перевести его с deepl.com) - person HHeckner; 21.02.2021

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

<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" defer>
    $(function () {   //  <- jquery is not yet initialized
      ...
    });
</script>

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

<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>
person Grigory Kislin    schedule 30.01.2017

element.addEventListener("load", function () {
    $('#tabs').tabs()
}, false);

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

person McKayla    schedule 02.05.2011
comment
Ага! У тебя вышло! Итак, я думаю, что некоторая комбинация этого и ответа амперсанда будет окончательным решением. Похоже, мне нужно будет последовательно загрузить jQuery, затем jQuery-UI, а затем код моей страницы, который полагается на оба. - person Kevin P. Rice; 02.05.2011
comment
IE ‹9 не поддерживает addEventListener :( - person brunoais; 20.02.2012

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

<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 < executeLater.length; c++) {
                executeLater[c]();
            }
        });
    })
</script>

....а потом...

<script>
    $(function() {
        alert("loaded");
    });
</script>
person asiop    schedule 14.01.2016
comment
Работает отлично, только что добавлены оба defer async. Спасибо - person Jodyshop; 19.08.2019

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

Изменить: немного более ясно

<html>
<head></head>
<body>
    <!-- Your normal content here -->
    <script type="text/javascript" src="http://path/to/jquery/jquery.min.js"></script>
    <script>//Put your jQuery code here</script>
</body>
</html>
person Dan    schedule 02.05.2011
comment
Это кажется следующим лучшим решением, но на самом деле это не то же самое. Хотя он позволяет загружать другие ресурсы, Google говорит (в первой предоставленной мной ссылке), скрипты должны быть загружены, проанализированы и выполнены, прежде чем браузер сможет начать отображать веб-страницу. Это означает, что загрузка jQuery внизу страницы означает, что страница все еще не отображается до тех пор, пока jQuery не будет проанализирован и выполнен. Есть ли способ загрузить его асинхронно и позволить ему выполнять свою работу после загрузки страницы? - person Kevin P. Rice; 02.05.2011
comment
Это было бы очень легко проверить. Сделайте себе красивый большой JS-файл размером 10 МБ, наполненный ерундой, и разместите его внизу своей страницы. Посмотрите, загружается ли в первую очередь ваш другой контент. - person Kevin Ennis; 02.05.2011
comment
kennis - ДА, сначала загружается другой контент, однако вопрос касается взаимодействия с пользователем. В частности, в мобильных браузерах время для синтаксического анализа JavaScript задерживает возможность взаимодействия пользователя со страницей. В инструментах разработчика Chrome временная шкала Evaluate Script для jQuery составляет ПОЛОВИНУ времени до запуска событий DOMContentLoaded и Load. Скрипт, который я могу отложить с кодом Google (в вопросе), не загружается и не выполняется до ПОСЛЕ этих событий. Я бы хотел, чтобы jQuery загружался / анализировался ПОСЛЕ отображения страницы. - person Kevin P. Rice; 02.05.2011
comment
@Kevin, в ссылке также указано, что ... обработка всех элементов ниже скрипта заблокирована до тех пор, пока браузер не загрузит код с диска и не выполнит его. По крайней мере, с настольными браузерами пользователь может начать взаимодействие со страницей до того, как страница будет полностью загружена. Какая разница во времени загрузки от первоначального запроса до тех пор, пока пользователь не сможет взаимодействовать со страницей (не обязательно с событием DOMContentLoaded) с вашими скриптами внизу и без скрипта вообще? - person Dan; 02.05.2011
comment
Я бы определенно протестировал (как можно лучше) оба метода, чтобы убедиться, что асинхронный режим загружается быстрее. Похоже, у Джереми есть код, который вы искали изначально. Удачи! - person Dan; 02.05.2011
comment
@Dan, код Drackir точно иллюстрирует мою проблему, заключающуюся в том, как отложить код рядом с ‹=== ЗАМЕТЬТЕ ЭТО до ПОСЛЕ загрузки jQuery (deferredfunctions.js). Также важно разместить внизу все теги ‹script›. Спасибо! - person Kevin P. Rice; 02.05.2011

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

<script type="text/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]);
        }

    }(window));
</script>

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

// myscript1.js 
(function(){ 

    function initMyjQueryDependency() {
        console.log('my code is executed after jquery is loaded!');
        // here my code that depends on jquery
    }

    if ( jQueryHasLoaded === true )
        initMyjQueryDependency();
    else
        document.body.addEventListener('jqueryloaded', initMyjQueryDependency, false);

}());

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

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

person mex23    schedule 19.11.2013
comment
Спасибо за этот новый ответ. - person Kevin P. Rice; 19.11.2013

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

<script type="text/javascript">

 // Add a script element as a child of the body
 function downloadJSAtOnload() {
 var element = document.createElement("script");
 element.src = "deferredfunctions.js";
 document.body.appendChild(element);
 $("#tabs").tabs(); // <==== NOTE THIS. This should theoretically run after the
                    // script has been appended, though you'll have to test this
                    // because I don't know if the JavaScript above will wait for
                    // the script to load before continuing
 }

 // Check for browser support of event handling capability
 if (window.addEventListener)
 window.addEventListener("load", downloadJSAtOnload, false);
 else if (window.attachEvent)
 window.attachEvent("onload", downloadJSAtOnload);
 else window.onload = downloadJSAtOnload;

</script>
person Richard Marskell - Drackir    schedule 02.05.2011
comment
Это ТОЧНО то, что я пробовал. Он НЕ ждет загрузки deferredfunctions.js (который я заменил на jQuery.js) перед выполнением кода «вкладок». Итак, как получить код вкладок для ожидания jQuery ?? Я мог бы поместить его в тот же файл, но только если я загружаю jQuery из Google CDN. - person Kevin P. Rice; 02.05.2011
comment
@Kevin R: А как насчет загрузки двух элементов скрипта, когда второй загружается с вашего сервера и содержит ваш код jQuery? Первый - это, конечно, сам jQuery. - person Richard Marskell - Drackir; 02.05.2011
comment
Помещение всего в один файл ДЕЙСТВИТЕЛЬНО работает. Раньше я пробовал использовать ДВА элемента скрипта для загрузки jQuery / jQuery-UI, но не для загрузки кода моей страницы. Позвольте мне попробовать ... Я подозреваю, что возникнут проблемы с тем, какой из них загрузится первым. - person Kevin P. Rice; 02.05.2011
comment
@Kevin R: Предположительно, первый, прикрепленный к DOM, будет выполнен первым, но, возможно, поскольку ваш код, скорее всего, будет меньше, чем jQuery, он будет запущен первым. Как насчет использования серверной части пользовательского агента и управления включенными файлами таким образом? Я знаю, что это не лучший вариант, но если вас беспокоят мобильные браузеры, возможно, на это стоит обратить внимание. - person Richard Marskell - Drackir; 02.05.2011
comment
Возможно, я весь мокрый, пытаясь отложить загрузку jQuery в первую очередь, но это кажется разумным и делает Google PageSpeed ​​ счастлив. Цепочка событий с помощью ответа Tylermwashburn, похоже, является способом загрузить все по порядку. Также ознакомьтесь с JSL JavaScript Loader, который, похоже, похож на то, что я пытаюсь сделать. Большое спасибо! - person Kevin P. Rice; 02.05.2011

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

<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 was loaded');
            jQueryLoaded = true;
            test();
        } else {
            alert('jqueryui was loaded');   
        }
    }

    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>Placeholder text goes here</p>
</body>
</html>

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

person Jeremy Battle    schedule 02.05.2011
comment
Джереми, спасибо - однако см. Мой ответ Кеннису (выше). Я бы хотел, чтобы jQuery загружался / оценивался / анализировался / выполнялся ПОСЛЕ загрузки страницы. - person Kevin P. Rice; 02.05.2011
comment
Отредактировал свой ответ, чтобы выполнить загрузку скриптов после запуска события window.load / onload. - person Jeremy Battle; 02.05.2011
comment
Джереми, еще раз спасибо - я собираюсь попробовать свойство 'async' ... однако см. Приведенный ниже код 'Drackir', который ТОЧНО то, что я пробовал. Результат: ДА, jQuery загружается с задержкой, но код «вкладок» (такой же, как это показывает Drackir) не ждет загрузки отложенного jQuery.js, и я получаю jquery undefined. Каким-то образом мне нужен обратный вызов или событие, чтобы узнать, когда jquery.js загружен и проанализирован. - person Kevin P. Rice; 02.05.2011
comment
Немного взлома, но технически вы можете выполнить цикл «занято-ожидание» и проверить, загружен ли jQuery перед запуском $ (# tabs) .tabs ();. Если это не так, выполните setTimeout и снова вызовите функцию. - person Dan; 02.05.2011
comment
Кевин, отредактировал еще раз. Работал для меня, дайте мне знать, работает ли он для ваших вкладок. - person Jeremy Battle; 02.05.2011
comment
Джереми, я основываюсь на твоем предложении ... скоро отправлю ответ. Оказывается, if ($) тестирует jQuery, а if ($. Ui) тестирует jQuery-UI ... вы можете видеть, куда я иду. Хотя опрос (цикл "занято-ожидание") является беспорядочным. Я бы предпочел найти событие, на которое можно было бы зацепиться. - person Kevin P. Rice; 02.05.2011
comment
@Jeremy, похоже, что «амперсанд» в конечном итоге указал на события, к которым можно подключиться, и показал, как связать несколько скриптов вместе. - person Kevin P. Rice; 02.05.2011

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

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;
person valmarv    schedule 25.09.2012
comment
Спасибо за ваш вклад! - person Kevin P. Rice; 28.09.2012

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

person Mike    schedule 17.12.2014

Есть простой прием, который использует Google Analytics.

Подготовка

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

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

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

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

// When jQuery is finaly ready
$(function() {
    // Replace previous implementation
    window.jQueryReady = function(fn) {
        // jQuery is loaded call immediately
        fn();
    }
    
    // Call all saved callbacks
    for (var i = 0; i < window.jQuery_store.length; ++i) {
        try {
            window.jQuery_store[i]();
        } catch (err) {
            console.log(err);
        }
    }
})

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

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

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

<script defer src=".../jquery.min.js">
<script defer src=".../bootstrap.min.js">
... any other plugins for jQuery you probably need
<script defer src=".../jquery-ready.js">

Это гарантирует, что сценарий jquery-ready.js будет выполнен только после выполнения jQuery.

использование

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

jQueryReady(function() {
    // jQuery is safe to use here
    $("div.to-be-hidden").hide();
})
person Seagull    schedule 16.10.2020
comment
Аккуратное решение. Я еще не пробовал это, но будет ли проблема с плагинами, которые ждут jQuery? - person Reigel; 04.11.2020
comment
Вы должны включать jquery-ready.js после всех плагинов. В этом случае jQueryReady будет вызываться только тогда, когда все плагины загружены. - person Seagull; 04.11.2020

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

person c-smile    schedule 02.05.2011
comment
Согласно этой ссылке: атрибут отсрочки поддерживается только Internet Explorer. OP, упомянутый в комментарии, что они используют Chrome, поэтому я предполагаю, что это ограничитель шоу. - person Richard Marskell - Drackir; 02.05.2011
comment
Я создаю общедоступный сайт, который должен обеспечивать широкую кроссбраузерную поддержку. Кроме того, проблема заключается не в отсрочке, а в знании того, когда отложенный код (jQuery) загружен и готов к вызову функций. - person Kevin P. Rice; 02.05.2011

Взгляните jQuery.holdReady()

«Удерживает или отменяет выполнение события готовности jQuery». (jQuery 1.6+)

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

person mikeycgto    schedule 29.05.2011
comment
Спасибо за этот комментарий. Похоже, что holdReady () не откладывает загрузку jQuery, а просто задерживает событие Ready. Чтобы прояснить мой вопрос: браузеры тратят определенное количество времени на загрузку и анализ всех файлов .js перед отображением страницы - мобильные браузеры особенно медленно анализируют код JS. Я хочу, чтобы страница отображалась еще до загрузки файлов .js. Таким образом, пользователь быстро видит страницу и может начать переваривать контент, пока файлы .js загружаются и анализируются. Следовательно, я хочу отложить фактическую загрузку файлов .js. - person Kevin P. Rice; 30.05.2011
comment
Я понимаю, о чем вы говорите. Некоторые из приведенных выше сценариев могут помочь в этом. Попробуйте использовать инструмент Chrome Audit, чтобы узнать, как улучшить скорость вашей страницы. - person mikeycgto; 09.06.2011

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

person Mirek Komárek    schedule 07.02.2014