При встраивании JavaScript в HTML-документ, где правильно размещать теги <script>
и включенный JavaScript? Я припоминаю, что их не следует размещать в разделе <head>
, но размещение в начале раздела <body>
тоже плохо, поскольку JavaScript должен быть разобран до того, как страница будет полностью отрисована (или что-то в этом роде). Таким образом, логичным местом для тегов <script>
остается конец раздела <body>
.
Итак, где же правильно размещать теги <script>
?
(Этот вопрос отсылает к этому вопросу, в котором было предложено перенести вызовы функций JavaScript из тегов <a>
в теги <script>
. Я'конкретно использую jQuery, но уместны и более общие ответы).
Вот что происходит, когда браузер загружает веб-сайт с тегом < script >
:
< script >
, ссылающийся на внешний файл скрипта.Шаг № 4 вызывает плохой пользовательский опыт. Ваш сайт в основном прекращает загрузку, пока вы не загрузите все сценарии. Если есть что-то, что ненавидят пользователи, это ожидание загрузки сайта.
Любой скрипт может вставить свой собственный HTML через document.write ()
или другие манипуляции DOM. Это подразумевает, что анализатор должен ждать, пока скрипт не будет загружен & выполняется, прежде чем он сможет безопасно проанализировать остальную часть документа. В конце концов, скрипт мог вставить свой собственный HTML в документ.
Однако большинство разработчиков JavaScript больше не манипулируют DOM * во время загрузки документа. Вместо этого они ждут, пока документ не будет загружен, прежде чем изменять его. Например:
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script type="text/javascript" src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
Javascript:
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
Поскольку ваш браузер не знает, что my-script.js не собирается изменять документ, пока он не будет загружен & Выполненный, анализатор прекращает анализ.
Старый подход к решению этой проблемы заключался в том, чтобы поместить теги < script >
в нижнюю часть вашего < body >
, поскольку это гарантирует, что анализатор не заблокирован до самого конца.
У этого подхода есть своя проблема: браузер не может начать загрузку сценариев, пока весь документ не будет проанализирован. Для больших сайтов с большими сценариями & таблицы стилей, возможность загрузки сценария как можно скорее очень важна для производительности. Если ваш сайт не загружается в течение 2 секунд, люди перейдут на другой сайт.
В оптимальном решении браузер начнет загружать ваши сценарии как можно скорее, одновременно анализируя остальную часть вашего документа.
Сегодня браузеры поддерживают атрибуты async
и defer
в скриптах. Эти атрибуты говорят браузеру, что безопасно продолжать анализ во время загрузки сценариев.
<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>
Сценарии с атрибутом async выполняются асинхронно. Это означает, что скрипт выполняется, как только он загружен, без блокирования браузера. Это означает, что скрипт 2 можно загрузить & выполняется до сценария 1.
Согласно http://caniuse.com/#feat=script-async, 94,57% всех браузеров поддерживают это.
<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>
Сценарии с атрибутом defer выполняются по порядку (т.е. сначала скрипт 1, затем скрипт 2). Это также не блокирует браузер.
В отличие от сценариев async, сценарии отсрочки выполняются только после загрузки всего документа.
Согласно http://caniuse.com/#feat=script-defer, 94,59% всех браузеров поддерживают это. 94,92% поддерживают это хотя бы частично.
Важное примечание о совместимости браузера: в некоторых случаях IE < = 9 может выполнять отложенные сценарии не по порядку. Если вам необходимо поддержать эти браузеры, сначала прочитайте this!
Текущее состояние - поместить сценарии в тег < head >
и использовать атрибуты async
или defer
. Это позволяет загружать ваши сценарии как можно скорее, не блокируя браузер.
Хорошо, что ваш сайт все еще должен правильно загружаться в 6% браузеров, которые не поддерживают эти атрибуты, ускоряя остальные 94%.
Непосредственно перед закрывающим тегом body, как указано на
http://developer.yahoo.com/performance/rules.html#js_bottom
Поместите скрипты в самый низ
Проблема, связанная со скриптами, заключается в том, что они блокируют параллельную загрузку. Спецификация HTTP/1.1 предполагает, что браузеры загружают не более двух компонентов параллельно с одного имени хоста. Если обслуживать изображения с нескольких хостов, то можно добиться параллельной загрузки более двух компонентов. Однако во время загрузки скрипта браузер не будет запускать другие загрузки, даже с разных хостов.
Неблокирующие теги сценариев можно размещать практически в любом месте:
<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
async
скрипт будет выполняться асинхронно, как только он будет доступенdefer
скрипт выполняется, когда документ закончил синтаксический анализasync defer
script возвращается к поведению defer, если async не поддерживаетсяТакие сценарии будут выполняться асинхронно / после готовности документа, что означает, что вы не можете сделать это:
<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
* might throw "jQuery is not defined" error
* defer will not work either
-->
Или это:
<script src="document.write(something).js" async></script>
<!--
* might issue "cannot write into document from an asynchronous script" warning
* defer will not work either
-->
Или это:
<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
* might throw "jQuery is not defined" error (no guarantee which script runs first)
* defer will work in sane browsers
-->
Или это:
<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
* might not locate #header (script could fire before parser looks at the next line)
* defer will work in sane browsers
-->
Сказав это, асинхронные сценарии предлагают эти преимущества:
Можно обойти проблемы с порядком выполнения, используя внешние сценарии, которые поддерживают обратные вызовы. Многие сторонние API-интерфейсы JavaScript теперь поддерживают неблокирующее выполнение. Вот пример загрузки API Карт Google асинхронно.
Стандартный совет, продвигаемый Yahoo! Команда Exceptional Performance должна поместить теги < script >
в конец тела документа, чтобы они не блокировали рендеринг страницы.
Но есть некоторые более новые подходы, которые предлагают лучшую производительность, как описано в этот ответ о времени загрузки файла JavaScript Google Analytics:
Есть некоторые < a href = "http://stevesouders.com/docs/googleio-20080529.ppt" > отличные слайды < / a > Стив Соудерс (эксперт по производительности на стороне клиента) о:
- Различные методы для параллельной загрузки внешних файлов JavaScript
- их влияние на время загрузки и рендеринг страницы
- какие индикаторы «в процессе» отображаются в браузере (например,. «загрузка» в строке состояния, курсор мыши песочных часов).
Если вы используете JQuery, то разместите javascript там, где вам удобнее всего, и используйте $(document).ready()
, чтобы убедиться, что все правильно загружено, прежде чем выполнять какие-либо функции.
В качестве примечания: я предпочитаю размещать все теги сценариев в разделе <head>
, так как это кажется наиболее чистым местом.
<script src="myjs.js"></script>
</body>
тег скрипта должен использоваться всегда перед закрытием тела или нижней частью в файле HTML .
затем вы можете увидеть содержимое страницы перед загрузкой файла js .
проверьте это, если требуется: http://stevesouders.com/hpws/rule-js-bottom.php
Вы можете отложить выполнение чем-то вроде jQuery, чтобы не было значения, где оно находится (за исключением небольшого хита во время анализа).
Современный подход в 2019 году использует сценарии типа модуля ES6 .
<script type="module" src="..."></script>
По умолчанию модули загружаются асинхронно и дефертируются. то есть. Вы можете разместить их в любом месте, и они будут загружаться параллельно и выполняться, когда страница заканчивает загрузку.
Различия между сценарием и модулем описаны здесь:
https://stackoverflow.com/a/53821485/731548
Выполнение модуля по сравнению со сценарием описано здесь:
https://developers.google.com/web/fundamentals/primers/modules#defer
Поддержка показана здесь:
https://caniuse.com/#feat=es6-модуль
Традиционный (и общепринятый) ответ - "снизу", поскольку в этом случае весь DOM будет загружен до того, как что-либо начнет выполняться.
Есть и несогласные, по разным причинам, начиная с имеющейся практики намеренного начала выполнения с события onload страницы.
Зависит от того, что если вы загружаете скрипт, необходимый для стилизации вашей страницы / использования действий на вашей странице (например, нажатие кнопки), вам лучше разместить его сверху. Если ваш стиль на 100% CSS и у вас есть все запасные варианты для действий кнопки, вы можете поместить его внизу.
Или лучше всего (если это не проблема), вы можете создать модальное окно загрузки, разместить свой JavaScript внизу своей страницы и заставить его исчезнуть при загрузке последней строки вашего скрипта. Таким образом, вы можете избежать использования пользователями действий на вашей странице до загрузки сценариев. А также избегайте неправильного стиля.
Включение сценариев в конце в основном используется там, где содержание / стили сайта должны быть показаны первыми.
включение сценариев в заголовок загружает сценарии раньше и может использоваться перед загрузкой всего веб-сайта.
если сценарии будут введены наконец, проверка будет проводиться только после загрузки всех стилей и дизайна, который не ценится для быстро реагирующих веб-сайтов.
Если вы все еще заботитесь о поддержке и производительности в IE < 10, лучше ВСЕГДА делать теги сценариев последними тегами вашего тела HTML. Таким образом, вы уверены, что остальная часть DOM была загружена, и вы не будете блокировать и рендеринг.
Если вас больше не волнует IE < 10, вы можете поместить свои сценарии в заголовок документа и использовать defer
, чтобы убедиться, что они запускаются только после загрузки вашего DOM (< script type = "text / javascript" src = "path / to / script1.js" delep > < / script >
). Если вы все еще хотите, чтобы ваш код работал в IE < 10, не забудьте даже обернуть ваш код в «window.onload»!
В зависимости от сценария и его использования наилучшим из возможных (с точки зрения загрузки страницы и времени рендеринга) может быть использование не обычного тега & lt; script > gt; сам по себе, а динамическое инициирование загрузки скрипта асинхронно.
Существуют несколько различных методов, но наиболее простым является использование document.createElement («script») при запуске события window.onload. Затем скрипт загружается первым, когда сама страница отображается, что не влияет на время, в течение которого пользователю приходится ждать появления страницы.
Это, естественно, требует, чтобы сам скрипт не был необходим для рендеринга страницы.
Для получения дополнительной информации см. Пост Сцепление асинхронных скриптов Стива Соудерса (создателя YSlow, но теперь в Google).
лучшее место для установки тега < script >
перед закрытием тега < / body >
, поэтому загрузка и выполнение не блокируют браузер для анализа html в документе,
Кроме того, загрузка файлов js извне имеет свои преимущества , как будто она будет кэширована браузерами и может ускорить время загрузки страницы , она разделяет код HTML и JavaScript и поможет лучше управлять базой кода **.
но современные браузеры также поддерживают некоторые другие оптимальные способы, такие как async
и defer
для загрузки внешних файлов javascript
.
Обычно выполнение HTML-страницы начинается строка за строкой. Когда внешний JavaScript < script > элемент встречается, синтаксический анализ HTML прекращается до загрузки JavaScript и готовится к исполнению. Это нормальное выполнение страницы можно изменить с помощью атрибута defer
и async
.
Defer
Когда используется атрибут defer, JavaScript загружается параллельно с синтаксическим анализом HTML, но будет выполняться только после завершения полного анализа HTML.
<script src="/local-js-path/myScript.js" defer></script>
Async
Когда используется атрибут async, JavaScript загружается, как только скрипт встречается, и после загрузки он будет выполняться асинхронно (параллельно) вместе с синтаксическим анализом HTML.
<script src="/local-js-path/myScript.js" async></script>
async
.async
, оба будут работать
параллельно вместе с синтаксическим анализом HTML, как только они загружаются
и доступно.defer
для обоих:defer
, тогда
script1 гарантированно будет выполнен первымasync
затем используйте свой скрипт без атрибутов и разместите его
прежде всего сценарии async
.ссылка: knowledgehills.com
Блоки сценариев DOM загружаются до загрузки и выполнения.
Если вы разместите скрипты в конце < body >
, весь DOM имеет шанс загрузить и визуализировать (страница будет «отображаться» быстрее). < script >
будет иметь доступ ко всем этим элементам DOM.
В другой стороны, размещение его после < body >
start или выше будет выполнять скрипт (где все еще нет элементов DOM).
Вы включаете jQuery, что означает, что вы можете разместить его в любом месте и использовать .ready ()
Я думаю, что это зависит от выполнения веб-страницы. Если страница, которую вы хотите отобразить, не может отображаться должным образом без первой загрузки JavaScript, сначала вы должны включить файл JavaScript. Но если вы можете отобразить / арендовать веб-страницу без первоначальной загрузки файла JavaScript, вам следует поместить код JavaScript внизу страницы. Поскольку он будет эмулировать быструю загрузку страницы, и с точки зрения пользователя может показаться, что эта страница загружается быстрее.
Вы можете разместить большинство ссылок < script >
в конце < body >
,
Но если на вашей странице есть активные компоненты, использующие внешние скрипты,
тогда их зависимость (файлы js) должна предшествовать этому (в идеале в теге head).
Перед концом тега тела для предотвращения и блокирования пользовательского интерфейса.
В конце HTML-документа
Так что это не повлияет на загрузку HTML-документа в браузере во время выполнения.
лучшее место для записи кода JavaScript
в конце кода документа после < / body > тег для загрузки документа, затем выполнить код js.
и если вы пишете код JQuery
, напишите
$(document).ready(function(){
//your code here...
});