Где я должен разместить теги <script> в разметке HTML?

1267

При встраивании JavaScript в документ HTML, где нужно разместить теги <script> и включить JavaScript? Кажется, я помню, что вы не должны размещать их в разделе <head>, но размещение в начале раздела <body> тоже плохо, так как JavaScript должен быть проанализирован до того, как страница будет полностью отображена ( или что-то типа того). Похоже, что конец раздела <body> остается логическим местом для тегов <script>.

Итак, где подходящее место для размещения тегов <script>?

(Этот вопрос ссылается на этот вопрос, в котором было высказано предположение, что вызовы функций JavaScript должны быть перенесены из тегов <a> в теги <script>. в частности, используя jQuery, но подходят и более общие ответы.)

Теги:

23 ответа

1509
Лучший ответ

Вот что происходит, когда браузер загружает веб-сайт с <script> на нем:

  1. Получить страницу HTML (например, index.html)
  2. Начните синтаксический разбор HTML
  3. Парсер встречает <script> ссылающийся на внешний файл сценария.
  4. Браузер запрашивает файл сценария. Между тем, синтаксический анализатор блокирует и останавливает анализ другого HTML на вашей странице.
  5. Через некоторое время скрипт загружается и затем выполняется.
  6. Парсер продолжает анализировать остальную часть документа HTML.

Шаг №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 может выполнять отложенные скрипты не в порядке. Если вам необходимо поддерживать эти браузеры, прочитайте это первым!

Вывод

Текущее состояние дел состоит в том, чтобы поместить скрипты в <head> и использовать атрибуты async или defer. Это позволяет загружать скрипты как можно скорее, не блокируя ваш браузер.

Хорошо, что ваш сайт должен по-прежнему правильно загружать 6% браузеров, которые не поддерживают эти атрибуты, в то же время ускоряя другие 94%.

  • 0
    Используя этот метод, какой будет лучший способ запустить javascript после загрузки всех js-файлов? В настоящее время я использую событие onload внутри открывающего тега body.
  • 0
    У кого-нибудь есть мысли по поводу этого подхода? feedthebot.com/pagespeed/defer-loading-javascript.html
Показать ещё 22 комментария
224

Перед тегом закрывающего тела, как указано на

http://developer.yahoo.com/performance/rules.html#js_bottom

Поместите скрипты в нижней части

Проблема, вызванная скриптами, заключается в том, что они блокируют параллельные загрузки. Спецификация HTTP/1.1 предполагает, что браузеры загружают не более двух компонентов параллельно по имени узла. Если вы обслуживаете свои изображения из нескольких имен хостов, вы можете получить более двух загрузок, которые будут происходить параллельно. Однако при загрузке script браузер не запускает никаких других загрузок даже на разных именах хостов.

  • 7
    Согласился с концепцией и ее объяснением. Но что будет, если пользователь начнет играть со страницей? Предположим, у меня есть выпадающий список AJAX, который начнет загружаться после того, как страница появится пользователю, но пока она загружается, пользователь нажимает на нее! А что, если «действительно нетерпеливый» пользователь отправит форму?
  • 8
    @Hermant Старый комментарий, но вы можете сделать трюк, отключив поля по умолчанию, затем включив их с помощью JS, когда DOM полностью загружен. Это то, что Facebook сейчас делает.
Показать ещё 5 комментариев
67

Неблокирующие теги script можно разместить где угодно:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async script будет выполняться асинхронно, как только он будет доступен
  • defer script выполняется, когда документ завершил синтаксический анализ
  • async defer script возвращается к отложенному поведению, если 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
-->

Сказав это, асинхронные скрипты предлагают следующие преимущества:

  • Параллельная загрузка ресурсов:
    Браузер может загружать таблицы стилей, изображений и другие сценарии параллельно, не дожидаясь загрузки и выполнения script.
  • Независимость от исходного порядка:
    Вы можете поместить скрипты внутри головы или тела, не беспокоясь о блокировке (полезно, если вы используете CMS). Порядок выполнения все еще имеет значение.

Можно обойти проблемы порядка выполнения, используя внешние скрипты, поддерживающие обратные вызовы. Многие сторонние API-интерфейсы JavaScript теперь поддерживают неблокирующее выполнение. Ниже приведен пример аффинной загрузки API Карт Google.

  • 2
    Это правильный ответ на сегодняшний день - использование этого подхода означает, что ваши виджеты легче держать самодостаточными, нет необходимости в причудливой логике включения <head> .
  • 1
    Я запутался, почему вы не можете использовать async или defer при включении jQuery, как вы указали во втором блоке: <script src="jquery.js" async></script> . Вы можете объяснить, почему? Я подумал, что мне нужно иметь асинхронный тег для повышения производительности (согласно принятому ответу), чтобы моя страница могла загружаться даже во время загрузки jQuery]. Спасибо!
Показать ещё 3 комментария
35

Стандартный совет, продвигаемый Yahoo! Команда Exceptional Performance - разместить теги <script> в конце тела документа, чтобы они не блокировали отображение страницы.

Но есть несколько новых подходов, которые предлагают более высокую производительность, как описано в этом ответе, о времени загрузки файла JavaScript Google Analytics:

Есть несколько отличные слайды от Steve Souders (эксперт по оценке на стороне клиента) о:

  • Различные методы загрузки внешних файлов JavaScript параллельно
  • их влияние на время загрузки и рендеринг страниц
  • какие индикаторы "в процессе" отображаются в браузере (например, "загрузка" в строке состояния, курсор мыши для песочных часов).
22

Если вы используете JQuery, тогда поместите javascript везде, где вы найдете его лучше, и используйте $(document).ready(), чтобы обеспечить правильную загрузку вещей перед выполнением каких-либо функций.

На стороне примечания: Мне нравятся все теги script в разделе <head>, поскольку это кажется самым чистым местом.

  • 14
    в голове ... э? <header> ?
  • 7
    Обратите внимание, что использование $(document).ready() не означает, что вы можете поместить свой JavaScript куда угодно - вы все равно должны поместить его после <script src=".../jquery.min.js"> где вы включите jQuery, чтобы $ существовал.
Показать ещё 3 комментария
9

XHTML не будет проверять, есть ли script где-либо, кроме элемента head., он может быть везде.

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

  • 1
    XHTML будет проверяться с помощью тегов скрипта в теле, как строгих, так и переходных. Однако теги стиля могут быть только в голове.
8
<script src="myjs.js"></script>
</body>
Тег

script должен использоваться всегда перед телом или Нижним в HTML файле.

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

проверьте это, если требуется: http://stevesouders.com/hpws/rule-js-bottom.php

  • 2
    Это на самом деле ответил на вопрос. Мне было интересно, что почти все опубликованные примеры не дают должного визуального контекста «конца страницы».
  • 1
    Этот ответ очень обманчив и, скорее всего, неверен. Статьи в Google и в MDN предполагают, что синхронный JS (который здесь имеет место) всегда блокирует построение DOM и анализ, что приведет к задержке первого рендеринга. Таким образом, вы не сможете увидеть содержимое страницы, пока файл JS не будет извлечен и не завершится, независимо от того, где вы разместили файл JS в документе HTML, если он является синхронным.
Показать ещё 1 комментарий
5

Размещение сценариев во внешних файлах имеет ряд преимуществ: он разделяет HTML и код, облегчает чтение и поддержку HTML и JavaScript. Кэшированные файлы JavaScript могут ускорить загрузку страниц. Получить страницу HTML (например, index.html). Начать анализ HTML. тег, ссылающийся на внешний файл скрипта. Браузер запрашивает файл скрипта. Тем временем парсер блокирует и прекращает анализ другого HTML-кода на вашей странице. Через некоторое время скрипт загружается и впоследствии выполняется. Парсер продолжает анализ остальной части HTML-документа.

5

Обычный (и общепринятый) ответ "внизу", потому что тогда весь DOM будет загружен, прежде чем что-либо начнет выполнение.

По разным причинам существуют инакомыслящие, начиная с доступной практики, чтобы преднамеренно начать выполнение с события onload на странице.

1

В зависимости от script и его использования наилучшим (с точки зрения загрузки страницы и времени рендеринга) может быть не использовать обычный <script> -tag per se, а динамически запускать загрузку script асинхронно.

Есть несколько разных методов, но наиболее прямолинейным является использование document.createElement( "script" ) при срабатывании события window.onload. Затем script загружается первым, когда сама страница была отображена, что не влияет на время, когда пользователю приходится ждать появления страницы.

Это, естественно, требует, чтобы сам script не нужен для рендеринга страницы.

Для получения дополнительной информации см. статью "Сцепление асинхронных скриптов" от Steve Souders (создатель YSlow, но теперь в Google).

0

Современный подход в 2019 году - использование скриптов типа модуля ES6.

<script type="module" src="..."></script>

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

Различия между скриптом и модулем описаны здесь:

https://stackoverflow.com/questions/39652618/classic-scripts-v-s-module-scripts-in-javascript

Выполнение модуля по сравнению со сценарием описано здесь:

https://developers.google.com/web/fundamentals/primers/modules#defer

Поддержка показана здесь:

https://caniuse.com/#feat=es6-module

0

Прежде всего, чтобы представить мою диаграмму и понять объяснение, вы должны знать этот цвет, что относится

Изображение 2158

вы должны поместить их в конец тела перед закрытием тега (body), это поможет вам игнорировать любую ошибку

<body>
  <script></script>
</body>

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

<head>
  <script></script>
</head>

но это приводит к очень плохому пользовательскому опыту, поскольку браузер на самом деле не делает ничего полезного во время загрузки файла скрипта. но что происходит, когда браузер встречает вышеуказанную строку в вашей разметке, это то, что происходит.

  1. Пауза в разборе документа.
  2. Сделайте запрос на получение файла.
  3. Выполните скрипт после его загрузки.
  4. Возобновите разбор документа.

Изображение 2159

поэтому, когда обнаруживается какая-либо ошибка, этот эффект присутствует в нашем контенте, но я хочу поместить свой скрипт в верхнюю часть моей разметки, и я не знаю, есть ли ошибка или нет, у вас есть два атрибута, я думаю, это поможет вам чтобы скачать разметку, а не с помощью скрипта

1. Первый атрибут

Асинхронизация. Когда вы добавляете атрибут асинхронности в тег сценария, произойдет следующее.

 <script src="myfile1.js" async></script>
 <script src="myfile2.js" async></script>
  1. Делайте параллельные запросы для получения файлов.
  2. Продолжайте анализ документа, как если бы он никогда не прерывался.
  3. Выполните отдельные сценарии в момент загрузки файлов.

Изображение 2160

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

ВНИМАНИЕ: Сценарии, которые вы программно вставляете в DOM, являются асинхронными по умолчанию, если вы явно не установили для их атрибута async значение false во время вставки.

  1. Второй атрибут

Defer: Defer очень похож на асинхронный с одним существенным отличием. Вот что происходит, когда браузер встречает скрипт с атрибутом defer.

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. Делайте параллельные запросы для извлечения отдельных файлов.
  2. Продолжайте анализ документа, как если бы он никогда не прерывался.
  3. Завершите анализ документа, даже если загружены файлы сценариев.
  4. Выполните каждый сценарий в том порядке, в котором они встречались в документе.

Как вы можете сказать, defer - это почти то, что вы хотите сделать в своих файлах. Тем не менее, из-за ограниченной поддержки браузера, это не жизнеспособный вариант на момент написания. Изображение 2161 ВНИМАНИЕ: Атрибуты async и defer игнорируются для сценариев, не имеющих атрибута src.

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

  • Если скрипт является модульным и не использует скрипты, используйте
    асинхронный.
  • Если скрипт использует другой сценарий или использует его, используйте defer.
  • Если скрипт небольшой и на него опирается асинхронный скрипт, используйте встроенный скрипт без атрибутов, размещенных над асинхронными скриптами.
0

Скрипты можно размещать в разделе HTML или в разделе HTML-страницы или в обоих.

<head>
<script></script>
</head>
or here
<body>
<script></script>
</body>

но для лучшей практики игнорировать любую ошибку вы должны поместить между тегом body, потому что, если какая-либо проблема обнаруживается в javascript, html не останавливается, но если вы используете только тег заголовка, если обнаруживается какая-либо проблема, которая остановит работу вашей страницы

Blockquote

0

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

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

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

0

Вы можете разместить большинство ссылок <script> в конце <body>,
Но если на вашей странице есть активные компоненты, которые используют внешние скрипты,
то их зависимость (js файлы) должна появиться до этого (в идеале в теге head).

0

Я думаю, что это зависит от исполнения веб-страницы. Если страница, которую вы хотите отобразить, не отображается должным образом, не загружая сначала JavaScript, тогда вы должны сначала включить файл JavaScript. Но если вы можете отображать/отображать веб-страницу без первоначальной загрузки файла JavaScript, тогда вы должны поместить код JavaScript внизу страницы. Поскольку он будет эмулировать быструю загрузку страницы, и с точки зрения пользователя кажется, что эта страница загружается быстрее.

0
  • Если вы все еще много заботитесь о поддержке и производительности в IE и 10, лучше ВСЕГДА сделать ваши теги script последними тегами вашего тела HTML. Таким образом, вы уверены, что остальная часть DOM была загружена, и вы не будете блокировать и рендеринг.

  • Если вам больше неинтересно об IE и 10, вы можете поместить свои сценарии в начало своего документа и использовать defer, чтобы убедиться, что они запускаются только после загрузки DOM (<script type="text/javascript" src="path/to/script1.js" defer></script>). Если вы все еще хотите, чтобы ваш код работал в IE < 10, не забудьте обернуть свой код в window.onload даже, хотя!

  • 0
    В принятом ответе это упоминается как «устаревшая рекомендация». Если вы по-прежнему имеете в виду это, вы, вероятно, должны предоставить какую-то ссылку, чтобы поддержать это.
0

Script блокирует загрузку DOM до ее загрузки и выполнения.

Если вы размещаете скрипты в конце <body>, все DOM имеют возможность загружать и отображать (страница будет "отображаться" быстрее). <script> будет иметь доступ ко всем этим элементам DOM.

В другой руке, помещающей его после <body> start или above, будет выполняться script (там, где еще нет элементов DOM).

Вы включаете jQuery, что означает, что вы можете разместить его там, где хотите, и . ready()

0

Зависит, если вы загружаете script, который необходим для стилизации вашей страницы/использования действий на вашей странице (например, одним нажатием кнопки), тогда лучше разместить ее сверху. Если ваш стиль составляет 100% CSS, и у вас есть все варианты возврата для действий кнопки, вы можете поместить его внизу.

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

-1

Мне больше смысла включать script после HTML. Поскольку большую часть времени мне нужен Dom для загрузки, прежде чем я выполнил свой script. Я мог бы поместить его в главный тег, но мне не нравятся все накладные расходы загрузчика документа. Я хочу, чтобы мой код был коротким, сладким и легким для чтения.

Я слышал, что старые версии сафари были quarky при добавлении вашего script за пределами основного тега, но я говорю, кто заботится. Я не знаю, чтобы кто-нибудь использовал этот старый дерьмо.

Хороший вопрос кстати.

-2

В конце HTML-документа

Таким образом, это не повлияет на загрузку HTML-документа в браузере во время выполнения.

-2

лучшее место, чтобы написать свой код JavaScript в конце кода документа после тега, чтобы загрузить документ, а затем выполнить код js. и если вы пишете код JQuery напишите

$(document).ready(function(){

//your code here...

});
  • 0
    он выдает SyntaxError
-7

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

ситуация такова:

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

определить хорошую практику не зависит от того, где.

чтобы поддержать вас, я упомянул следующее:

вы можете разместить:

и страница будет загружаться линейно

загружается асинхронно с другим контентом

содержимое страницы загрузится до и после завершения загрузки скриптов.

Хорошая практика здесь будет, когда будет реализовывать каждый?

Надеюсь, что я был полезен, все просто ответила на эту проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню