Внешние скрипты, порядок исполнения
Если JavaScript-кода много – его выносят в отдельный файл, который подключается в HTML:
PHP:
<script src="/path/to/script.js"></script>
Браузер сам скачает скрипт и выполнит.
Можно указать и полный URL, например:
PHP:
<script src="https://cdnjs.cloudflare.com/ajax/libs/script.js/4.3.0/script.js"></script>
Чтобы подключить несколько скриптов, используйте несколько тегов:
PHP:
<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>
Вот так не сработает:
PHP:
<script src="file.js">
alert(1); // так как указан src, то внутренняя часть тега игнорируется
</script>
PHP:
<script src="file.js"></script>
<script>
alert( 1 );
</script>
Асинхронные скрипты: defer/async
Браузер загружает и отображает HTML постепенно. Особенно это заметно при медленном интернет-соединении: браузер не ждёт, пока страница загрузится целиком, а показывает ту часть, которую успел загрузить. Если браузер видит тег <script>, то он по стандарту обязан сначала выполнить его, а потом показать оставшуюся часть страницы.
Например, в примере ниже – пока все кролики не будут посчитаны – нижний <p> не будет показан:
PHP:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Начинаем считать:</p>
<script>
alert( 'Первый кролик!' );
alert( 'Второй кролик!' );
alert( 'Третий кролик!' );
</script>
<p>Кролики посчитаны!</p>
</body>
</html>
PHP:
<html>
<head>
<script src="big.js"></script>
</head>
<body>
Этот текст не будет показан, пока браузер не выполнит big.js.
</body>
</html>
Вот пример, с подобным скриптом (стоит искусственная задержка загрузки):
PHP:
<p>Важная информация не покажется, пока не загрузится скрипт.</p>
<script src="https://js.cx/hello/ads.js?speed=0"></script>
<p>...Важная информация!</p>
Атрибут async
Поддерживается всеми браузерами, кроме IE9. Скрипт выполняется полностью асинхронно. То есть, при обнаружении <script async src="..."> браузер не останавливает обработку страницы, а спокойно работает дальше. Когда скрипт будет загружен – он выполнится.
Атрибут defer
Поддерживается всеми браузерами, включая самые старые IE. Скрипт также выполняется асинхронно, не заставляет ждать страницу, но есть два отличия от async.
Первое – браузер гарантирует, что относительный порядок скриптов с defer будет сохранён.
То есть, в таком коде (с async) первым сработает тот скрипт, который раньше загрузится:
PHP:
<script src="1.js" async></script>
<script src="2.js" async></script>
PHP:
<script src="1.js" defer></script>
<script src="2.js" defer></script>
Второе отличие – скрипт с defer сработает, когда весь HTML-документ будет обработан браузером.
Например, если документ достаточно большой
PHP:
<script src="async.js" async></script>
<script src="defer.js" defer></script>
async вместе с defer
При одновременном указании async и defer в современных браузерах будет использован только async, в IE9- – только defer (не понимает async).
Атрибуты async/defer – только для внешних скриптов.
Атрибуты async/defer работают только в том случае, если назначены на внешние скрипты, т.е. имеющие src. При попытке назначить их на обычные скрипты <script>…</script>, они будут проигнорированы.
Тот же пример с async:
PHP:
<p>Важная информация теперь не ждёт, пока загрузится скрипт...</p>
<script async src="https://js.cx/hello/ads.js?speed=0"></script>
<p>...Важная информация!</p>
Эти атрибуты давно «в ходу». Большинство современных систем рекламы и счётчиков знают про эти атрибуты и используют их. Перед вставкой внешнего тега <script> понимающий программист всегда проверит, есть ли у него подобный атрибут. Иначе медленный скрипт может задержать загрузку страницы. Для продвинутого читателя, который знает, что теги <script> можно добавлять на страницу в любой момент при помощи самого javascript, заметим, что скрипты, добавленные таким образом, ведут себя так же, как async. То есть, выполняются как только загрузятся, без сохранения относительного порядка. Если же нужно сохранить порядок выполнения, то есть добавить несколько скриптов, которые выполнятся строго один за другим, то используется свойство script.async = false.
Выглядит это примерно так:
PHP:
function addScript(src){
var script = document.createElement('script');
script.src = src;
script.async = false; // чтобы гарантировать порядок
document.head.appendChild(script);
}
addScript('1.js'); // загружаться эти скрипты начнут сразу
addScript('2.js'); // выполнятся, как только загрузятся
addScript('3.js'); // но, гарантированно, в порядке 1 -> 2 -> 3
- Скрипты вставляются на страницу как текст в теге <script>, либо как внешний файл через <script src="путь"></script>.
- Специальные атрибуты async и defer используются для того, чтобы пока грузится внешний скрипт – браузер показал остальную (следующую за ним) часть страницы. Без них этого не происходит.
- Разница между async и defer: атрибут defer сохраняет относительную последовательность скриптов, а async – нет. Кроме того, defer всегда ждёт, пока весь HTML-документ будет готов, а async – нет.
Автор темы: Serg_Brain