\n\n```\n\n#### **Современные исключения и атрибуты скриптов**\n\nВ современных разработках строгое правило \"скрипты только в конце `body`\" смягчается благодаря атрибутам:\n\n* **`async`**: Скрипт загружается асинхронно, **не блокируя парсинг**. Он выполнится сразу после загрузки, независимо от порядка в документе. Используется для независимых скриптов (например, аналитика).\n ```html\n \n \n \n \n ```\n* **`defer`**: Скрипт загружается асинхронно, но выполнится **строго после завершения парсинга HTML**, перед событием `DOMContentLoaded`. Сохраняет порядок исполнения нескольких скриптов с `defer`. Идеально для скриптов, зависящих от DOM.\n ```html\n \n \n \n \n \n ```\n\n### **Итог и современный подход**\n\n**Итоговое правило:**\n* **Все критически важные для первого рендеринга стили (Critical CSS)** должны быть загружены или встроены в ``.\n* **Скрипты, манипулирующие DOM и без атрибутов `async/defer`**, следует размещать в конце ``.\n* **Независимые скрипты** можно размещать в `` с атрибутом `async`.\n* **Основная логика приложения**, зависящая от DOM, может быть размещена в `` с атрибутом `defer` — это современная и эффективная практика, объединяющая раннее начало загрузки скрипта и корректное время его выполнения.\n\nТаким образом, разделение основано на понимании модели загрузки браузера: стили нужны **до** рендеринга, а скрипты, работающие с DOM, — **после** его построения. Использование `defer/async` позволяет оптимизировать этот процесс еще дальше.","dateCreated":"2026-04-06T18:30:39.258280","upvoteCount":0,"author":{"@type":"Person","name":"deepseek-v3.2"}}}}
← Назад к вопросам

Почему стили добавляем в тег head, а script в тег body?

1.3 Junior🔥 51 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Зачем стили в <head> и скрипты в <body>?

Этот вопрос касается фундаментальных принципов оптимизации процесса рендеринга веб-страницы и обеспечения корректной работы скриптов. Расположение ресурсов в определенных частях HTML документа — не случайность, а следствие спецификации браузеров и многолетней практики веб-разработки.

Размещение CSS в <head>

Основная причина — предотвращение FOUC (Flash Of Unstyled Content). Это явление, когда браузер показывает нестилизованный HTML до полной загрузки и применения CSS.

  • Процесс рендеринга: Браузер строит DOM (объектная модель документа) и CSSOM (объектная модель CSS) параллельно, но для отрисовки дерева рендеринга (Render Tree) ему необходимо объединить их. Render Tree содержит только элементы, которые будут визуально отображены, с примененными стилями.
  • Блокировка рендеринга: CSS считается ресурсом, блокирующим рендеринг. Если браузер встречает внешнюю таблицу стилей (<link rel="stylesheet">) в <body>, он может начать рендерить часть контента до ее загрузки, затем остановиться, загрузить стили, пересчитать Render Tree и перерисовать страницу. Это вызывает FOUC и лишние вычисления.
  • Спецификация HTML: Согласно рекомендациям, стили должны быть объявлены как можно раньше. Размещение в <head> гарантирует, что браузер получит информацию о стилях до начала построения Render Tree для любого элемента в <body>.
<!-- Правильно: CSS в head -->
<head>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- Контент -->
</body>

Если скрипт загружает критически важные стили динамически, иногда используется прием встраивания ключевых стилей прямо в <head> через <style> блок, чтобы избежать FOUC.

Размещение скриптов <script> в конце <body>

Основная причина — избежание блокировки парсинга и рендеринга DOM. Скрипты, особенно без специальных атрибутов, могут существенно замедлить загрузку страницы.

  • Блокировка парсинга: Когда браузер встречает обычный <script> без атрибутов defer или async, он немедленно остановит парсинг HTML, выполнит загрузку и исполнение скрипта, и только затем продолжит строить DOM. Это потому, что скрипт может потенциально изменять DOM (например, через document.write). Если такой скрипт расположен в <head> или в начале <body>, пользователь будет долго видеть пустую страницу (белый экран).
  • Доступность DOM: Скрипты, которые манипулируют DOM (например, добавляют интерактивность), должны выполняться после того, как соответствующие элементы DOM уже созданы. Если скрипт в <head> попытается найти элемент document.getElementById('myButton'), этот элемент еще не будет существовать в DOM, что приведет к ошибке.
  • Практическое размещение: Поэтому традиционно внешние скрипты и inline-скрипты размещают перед закрывающим тегом </body>. Это гарантирует, что весь DOM уже построен.
<!-- Правильно: скрипты в конце body -->
<body>
    <!-- Весь контент и DOM элементы здесь -->
    <div id="app"></div>

    <!-- Скрипты после всего контента -->
    <script src="app.js"></script>
</body>

Современные исключения и атрибуты скриптов

В современных разработках строгое правило "скрипты только в конце body" смягчается благодаря атрибутам:

  • async: Скрипт загружается асинхронно, не блокируя парсинг. Он выполнится сразу после загрузки, независимо от порядка в документе. Используется для независимых скриптов (например, аналитика).
    <head>
        <!-- Аналитика не блокирует рендеринг -->
        <script async src="analytics.js"></script>
    </head>
    
  • defer: Скрипт загружается асинхронно, но выполнится строго после завершения парсинга HTML, перед событием DOMContentLoaded. Сохраняет порядок исполнения нескольких скриптов с defer. Идеально для скриптов, зависящих от DOM.
    <head>
        <!-- Скрипты с defer можно размещать в head -->
        <script defer src="vendor.js"></script>
        <script defer src="app.js"></script>
    </head>
    

Итог и современный подход

Итоговое правило:

  • Все критически важные для первого рендеринга стили (Critical CSS) должны быть загружены или встроены в <head>.
  • Скрипты, манипулирующие DOM и без атрибутов async/defer, следует размещать в конце <body>.
  • Независимые скрипты можно размещать в <head> с атрибутом async.
  • Основная логика приложения, зависящая от DOM, может быть размещена в <head> с атрибутом defer — это современная и эффективная практика, объединяющая раннее начало загрузки скрипта и корректное время его выполнения.

Таким образом, разделение основано на понимании модели загрузки браузера: стили нужны до рендеринга, а скрипты, работающие с DOM, — после его построения. Использование defer/async позволяет оптимизировать этот процесс еще дальше.