Javascript неблокирующие скрипты, почему бы просто не поставить все скрипты перед тегом </ body>?
Чтобы javascript не блокировал рендеринг веб-страницы, мы не можем просто поместить все наши JS-файлы / код для загрузки / выполнения просто перед закрытием </body>
тег?
Все файлы и код JS будут загружаться и выполняться только после рендеринга всей страницы, так что зачем нужны хитрости, подобные предложенным в этой статье, о неблокирующих методах загрузки файлов JS. Он в основном предлагает использовать такой код:
document.getElementsByTagName("head")[0].appendChild(script);
для того, чтобы отложить скрипт, позволяющий отображать веб-страницу, что приводит к высокой скорости рендеринга веб-страницы.
Но без использования этого типа техники неблокирования (или других подобных техник) мы бы не достигли того же результата неблокирования, просто поместив все наши файлы JS (для загрузки / выполнения) перед закрытием </body>
тег?
Я еще больше удивлен, потому что автор (в той же статье) предлагает поставить свой код до закрытия </body>
тег (см. раздел "Размещение скриптов" статьи), поэтому он в основном загружает скрипты перед закрытием </body>
пометить в любом случае. Зачем тогда его код?
Я в замешательстве, любая помощь приветствуется, спасибо!
ОБНОВИТЬ
К сведению, 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 ответа
Если вы хотите асинхронные сценарии. Используйте асинхронный тег (HTML5), если он доступен в браузере, в котором вы находитесь. Это то, что делает Google Analytics в опубликованном вами коде (особенно в строке ga.async = true
MDN Link, прокрутите вниз для асинхронного).
Однако это может привести к тому, что ваш скрипт будет загружаться в произвольное время во время загрузки страницы, что может быть нежелательно. Стоит задать себе следующие вопросы, прежде чем использовать async.
Не нужно вводить пользователя? Затем с помощью атрибута async.
Нужно реагировать на кнопки или навигацию? Затем вам нужно поместить их в верхней части страницы (в заголовке) и не использовать асинхронный тег.
Асинхронные сценарии выполняются в любом порядке, поэтому, если ваш сценарий зависит, скажем, от jQuery, а jQuery загружен в другом теге, ваш сценарий может выполняться раньше, чем сценарий jQuery, что приводит к ошибкам.
Почему люди не помещают вещи внизу тега body? Если сценарий загружается достаточно времени, чтобы замедлить / приостановить загрузку веб-сайта, вполне возможно, что этот сценарий приостановит / повесит веб-сайт после загрузки веб-сайта (ожидайте различного поведения в разных браузерах) - веб-сайт не отвечает (нажмите на кнопку, и ничего не происходит). В большинстве случаев это не идеально, поэтому был изобретен атрибут async.
В качестве альтернативы, если загрузка вашего скрипта занимает много времени - вы можете (после тестирования) минимизировать и объединить ваш скрипт перед его отправкой на сервер.
Я рекомендую использовать require.js для минимизации и объединения, его легко запустить и использовать.
Минимизация уменьшает объем данных, которые необходимо загрузить.
Объединение сценариев сокращает количество "обращений" к серверу (для удаленного сервера с пингом 200 мс 5 запросов занимает 1 секунду).
Вообще говоря нет. Даже если сценарии будут загружены после всего содержимого страницы, загрузка и выполнение сценариев заблокирует страницу. Причиной тому является возможность наличия команд записи в ваших скриптах.
Однако, если все, чего вы хотите добиться, это скорость загрузки содержимого страницы, то результат размещения тегов скрипта прямо перед </body>
тег такой же, как для динамического создания тегов скрипта. Наиболее существенным отличием является то, что при загрузке сценариев обычным статическим способом они выполняются один за другим, другими словами, нет параллельного выполнения файла сценария (в старых браузерах это же верно и для загрузки сценария).
Одно из преимуществ асинхронной загрузки (особенно с чем-то вроде фрагмента аналитики) заключается в том, что, по крайней мере, если вы поместите его сверху, он будет загружен как можно скорее, не тратя время на рендеринг страницы. Так что с аналитикой шансы на самом деле отследить пользователя, прежде чем он покинет страницу (возможно, до того, как страница была полностью загружена) будет выше.
И insertBefore используется вместо append, потому что, если я правильно помню, там была ошибка (я думаю, что в некоторых версиях IE см. Также ссылку ниже, чтобы найти что-то в комментариях об этом).
Для меня эта ссылка: Async JS был самым полезным, что я нашел до сих пор. Тем более, что это также поднимает проблему, что даже с аналитическим кодом googles событие onload все равно будет заблокировано (по крайней мере, в некоторых браузерах). Если вы хотите, чтобы этого не произошло, лучше присоедините функцию к событию onload.
Для размещения асинхронного фрагмента внизу, это на самом деле объясняется в ссылке, которую вы разместили. Кажется, он просто делает это, чтобы убедиться, что DOM полностью загружен без использования события onload. Таким образом, это может зависеть от того, что вы делаете в скриптах: если вы не манипулируете DOM, не должно быть никаких причин добавлять его внизу тела. Кроме того, я лично предпочел бы добавить его в событие onload в любом случае.