Javascript неблокирующие скрипты, почему бы просто не поставить все скрипты перед тегом </body>? - PullRequest
13 голосов
/ 26 июля 2011

Во избежание блокирования рендеринга javascript веб-страницы, мы не можем просто поместить все наши JS-файлы / код для загрузки / выполнения просто перед закрывающим тегом </body>?

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

document.getElementsByTagName("head")[0].appendChild(script);

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

Но без использования этого типа неблокирующей техники (или других подобных техник) , мы не добьемся того же неблокирующего результата, просто поместив все наши файлы JS (для загрузки / выполнения) ) до закрывающего тега </body>?

Я еще больше удивлен, потому что автор (в той же статье) предлагает поместить свой код перед закрывающим тегом </body> (см. Раздел «Размещение скриптов»), поэтому он в основном загружает скрипты в любом случае до закрывающего тега </body>. Зачем тогда его код?

Я в замешательстве, любая помощь приветствуется, спасибо!


UPDATE

К вашему сведению, Google Analytics использует аналогичную неблокирующую технику для загрузки своего кода отслеживания:

<script type="text/javascript">
...
(function() 
{
   var ga = document.createElement('script');
   ga.type = 'text/javascript';
   ga.async = true;
   ga.src = 'your-script-name-here.js';
   var s = document.getElementsByTagName('script')[0];
   s.parentNode.insertBefore(ga, s); //why do they insert it before the 1st script instead of appending to body/head could be the hint for another question.
})();
</script>
</head>

Ответы [ 3 ]

1 голос
/ 17 апреля 2015

Если вам нужны асинхронные сценарии. Используйте асинхронный тег (HTML5), если он доступен в браузере, в котором вы находитесь. Это то, что Google Analytics делает в опубликованном вами коде (особенно в строке).ga.async = true MDN Link, прокрутите вниз для асинхронного ).

Однако это может привести к загрузке вашего скрипта в произвольные моменты времени при загрузке страницы - что может быть нежелательно.Стоит задать себе следующие вопросы, прежде чем выбрать использование async.

Не нужно вводить пользователя? Затем использовать атрибут async.

Необходимо ответитьк кнопкам или навигации? Тогда вам нужно поместить их в верхнюю часть страницы (в заголовке) и не использовать асинхронный тег.

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

Почему не люди помещают вещи внизу тега body? Если скрипт загружается достаточно времени, чтобы замедлить / приостановить загрузку сайта,вполне возможно, что этот сценарий приостановит / повесит веб-сайт после загрузки веб-сайта (ожидайте различного поведения в разных браузерах) - в результате ваш веб-сайт перестанет отвечать на запросы (нажмите кнопку, и ничего не произойдет).В большинстве случаев это не идеально, поэтому был изобретен атрибут async.

В качестве альтернативы, если загрузка скрипта занимает много времени - вы можете (после тестирования) минимизировать и объединить ваш скрипт перед отправкой на сервер.

Я рекомендую использовать require.js для минимизации и объединения, его легко запустить и использовать.

Сокращение сокращает объем данных, которые необходимо загрузить.

Объединение сценариев сокращает количество "обращений" к серверу (для удаленного сервера с пингом 200 мс 5 запросов занимает 1 секунду).

1 голос
/ 28 июля 2011

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

Однако, если все, чего вы хотите добиться, - это скорость загрузки содержимого страницы, результат размещения тегов сценария непосредственно перед тегом </body> такой же, как и при динамическом создании тегов сценария. Наиболее существенным отличием является то, что при загрузке сценариев обычным статическим способом они выполняются один за другим, другими словами, нет параллельного выполнения файла сценария (в старых браузерах это же верно и для загрузки сценария).

0 голосов
/ 28 июля 2011

Одним из преимуществ асинхронной загрузки (особенно с чем-то вроде фрагмента аналитики) является, по крайней мере, если вы поместите его сверху, то он будет загружен как можно скорее, без затрат времени на рендеринг страницы. Таким образом, в случае с аналитикой шансы реально отследить пользователя до того, как он покинет страницу (возможно, до полной загрузки страницы), будут выше.

И insertBefore используется вместо append, потому что, если я правильно помню, там была ошибка (я думаю, что в некоторых версиях IE, см. Также ссылку ниже, есть кое-что в комментариях об этом).

Для меня это ссылка: Async JS был самым полезным, что я нашел до сих пор. Тем более, что это также поднимает проблему, что даже с аналитическим кодом googles событие onload все равно будет заблокировано (по крайней мере, в некоторых браузерах). Если вы хотите, чтобы этого не произошло, лучше присоедините функцию к событию onload.

Для размещения асинхронного фрагмента внизу, что на самом деле объясняется в размещенной вами ссылке. Кажется, он просто делает это, чтобы убедиться, что DOM полностью загружен без использования события onload. Таким образом, это может зависеть от того, что вы делаете в скриптах: если вы не манипулируете DOM, не должно быть никаких причин добавлять его внизу тела. Кроме того, я лично предпочел бы добавить его в событие onload в любом случае.

...