НейроАгент

Размещение тегов script: Руководство по производительности Head vs Body

Узнайте оптимальное размещение тегов script в HTML. Изучите современные стратегии async/defer, рекомендации по jQuery и лучшие практики для ускорения загрузки страницы.

Вопрос

Где размещать теги <script> в HTML-разметке?

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

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

(Я использую jQuery, но также подойдут более общие ответы.)

НейроАгент

Размещение тегов <script> в HTML-разметке зависит от ваших конкретных потребностей. Современные лучшие практики теперь рекомендуют использование атрибутов async и defer для загрузки скриптов без блокировки отрисовки страницы. Хотя традиционно теги размещались в конце элемента <body>, оптимальный подход варьируется в зависимости от важности скриптов и их зависимостей.

Содержание

Традиционное размещение скриптов

Исторически разработчики размещали теги <script> в конце элемента <body> перед закрывающим тегом </body>. Этот подход стал популярным по нескольким причинам:

Почему предпочтительны конец body: Теги скриптов внутри элемента head будут загружаться и интерпретироваться до того, как будет отрисован какой-либо HTML, что блокирует отрисовку HTML/CSS. Теги скриптов в конце тега body не блокируют HTML/CSS, и вы можете работать с DOM только после его построения.

Однако у этого традиционного подхода есть значительные ограничения:

  • Задержка загрузки: Браузер не может начать загрузку скриптов до самого конца разбора HTML
  • Последовательная загрузка: Скрипты загружаются один за другим, а не параллельно
  • Блокировка отрисовки: Хотя это лучше, чем размещение в head, все еще задерживает выполнение скриптов до завершения разбора DOM

Согласно обсуждению на Stack Overflow, “старый способ решения этой проблемы заключался в размещении тегов <script> в конце вашего <body>, поскольку это гарантирует, что парсер не будет заблокирован до самого конца.”

Современные стратегии загрузки скриптов

Современный подход использует атрибуты async и defer для оптимизации загрузки скриптов без ущерба для функциональности:

Атрибут Async

html
<script src="analytics.js" async></script>
  • Загружает скрипт без блокировки разбора HTML
  • Выполняется сразу после завершения загрузки (вне порядка)
  • Лучше всего подходит для независимых скриптов, которые не зависят от других скриптов
  • Согласно документации MDN, “лучше всего использовать async, когда скрипты на странице выполняются независимо друг от друга и не зависят от других скриптов на странице”

Атрибут Defer

html
<script src="jquery.js" defer></script>
<script src="app.js" defer></script>
  • Загружает скрипт без блокировки разбора HTML
  • Выполняется в том порядке, в котором они появляются в документе, после завершения разбора DOM
  • Лучше всего подходит для скриптов, которые зависят друг от друга или требуют доступа к полному DOM
  • Как объясняется на JavaScript.info, “браузер получает инструкцию загружать скрипт в фоновом режиме, пока он продолжает разбирать HTML-документ”

Приоритет атрибутов

Если указаны оба атрибута async и defer, async имеет приоритет в современных браузерах, в то время как более старые браузеры, которые поддерживают defer, но не async, перейдут на режим defer.


Рекомендации по jQuery

Для jQuery современные практики эволюционировали:

Традиционное размещение jQuery

html
<!-- Старый подход - конец body -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="your-app.js"></script>
</body>

Современное размещение jQuery с Defer

html
<!-- Современный подход - head с defer -->
<head>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
  <script src="your-app.js" defer></script>
</head>

Согласно экспертным рекомендациям, “библиотечные скрипты, такие как библиотека jQuery”, можно размещать в секции head, особенно при использовании defer для предотвращения блокировки.

Критические скрипты в Head

Для скриптов, критически важных для содержимого страницы и которые должны загружаться в первую очередь, таких как аналитика, API или скрипты аутентификации, “рекомендуется размещать их в секции head HTML-страницы” с async или defer.

Влияние на производительность

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

Размещение в Head (Без Async/Defer)

  • Плюсы: Скрипты загружаются рано
  • Минусы: Полностью блокирует отрисовку HTML/CSS
  • Случай использования: Только для очень маленьких, критически важных скриптов

Размещение в конце Body (Традиционный)

  • Плюсы: Не блокирует отрисовку
  • Минусы: Задерживает загрузку и выполнение скриптов
  • Случай использования: Устаревшие сайты или когда async/defer не поддерживаются

Head с Async/Defer

  • Плюсы: Ранняя загрузка без блокировки отрисовки
  • Минусы: Требует понимания порядка выполнения
  • Случай использования: Современные веб-сайты с правильным управлением зависимостями

Как отмечено в исследованиях, “размещайте теги <script> в <head> с async или defer для раннего начала загрузки, или в конце <body> для скриптов без этих атрибутов.”

Практическое руководство по реализации

Пошаговая реализация лучших практик

  1. Определите зависимости скриптов

    • Критические скрипты (аналитика, аутентификация)
    • Зависимости библиотек (jQuery, фреймворки)
    • Логика приложения
    • Интеграции с сторонними сервисами
  2. Выберите стратегию загрузки

    html
    <!-- Критические независимые скрипты -->
    <script src="critical-script.js" async></script>
    
    <!-- Скрипты, зависящие от других -->
    <script src="jquery.js" defer></script>
    <script src="app.js" defer></script>
    
  3. Разместите в соответствии со стратегией

    html
    <head>
      <!-- Критические скрипты с async -->
      <script src="analytics.js" async></script>
      
      <!-- Отложенные скрипты -->
      <script src="jquery.js" defer></script>
    </head>
    
    <body>
      <!-- Содержимое страницы -->
      
      <!-- Некритические скрипты без async/defer -->
      <script src="legacy-script.js"></script>
    </body>
    

Советы по оптимизации производительности

  • Используйте fetchpriority="high" для критических скриптов
  • Минимизируйте встроенные скрипты в head
  • Рассмотрите использование модульных скриптов для современных приложений
  • Используйте хостинг на CDN для лучшего кэширования

Когда использовать каждый подход

Сценарий Рекомендуемое размещение Обоснование
Критическая аналитика Head с async Ранняя загрузка, независимое выполнение
jQuery + зависимые скрипты Head с defer Сохраняет порядок выполнения, ранняя загрузка
Трекеры сторонних сервисов Конец body Совместимость с legacy, некритично
Устаревшие приложения Конец body Максимальная совместимость с браузерами
Современные SPA Head с defer или async Оптимизированная загрузка, лучшая производительность

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

Распространенные ошибки, которых следует избегать

  1. Смешивание блокирующих и неблокирующих скриптов

    • Не размещайте некоторые скрипты в head без async/defer, а другие в body
    • Это создает непредсказуемые паттерны загрузки
  2. Игнорирование зависимостей скриптов

    • Использование async для скриптов, которые зависят друг от друга
    • Неучет порядка выполнения при использовании defer
  3. Чрезмерное использование встроенных скриптов

    • Большие встроенные скрипты в head блокируют отрисовку
    • Перемещайте во внешние файлы с соответствующими атрибутами загрузки
  4. Забывание о совместимости с браузерами

    • Не тестирование поведения async/defer в старых браузерах
    • Отсутствие резервных вариантов для критически важного функционала

Как отмечают разработчики Reddit, “хорошей практикой является размещение в head с использованием async или defer. Для старых браузеров распространено размещение после тега body.”

Заключение

Оптимальное размещение тегов <script> в HTML значительно эволюционировало вместе с современными практиками веб-разработки. Вот ключевые выводы:

  1. Современная лучшая практика: Используйте атрибуты async и defer для размещения скриптов в <head> без блокировки отрисовки
  2. Размещение jQuery: Может размещаться в head с атрибутом defer для ранней загрузки при сохранении порядка выполнения
  3. Критические скрипты: Размещайте в head с async для независимой, ранней загрузки функциональности
  4. Устаревшие скрипты: Размещение в конце body остается приемлемым для некритических скриптов без атрибутов загрузки
  5. Фокус на производительности: Приоритет отдавайте ранней загрузке с неблокирующими атрибутами, а не традиционному размещению

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

Источники

  1. Does the