Когда сайт открывается в браузере за секунду, чувствуется магия — и почти всегда за этим стоит грамотное подключение JavaScript. Прошла эпоха, когда этот вопрос обсуждали лениво на последней странице учебника. Теперь — это реальный инструмент покорения скорости загрузки и поисковой оптимизации. По полям браузерной консоли гуляют легенды: одни считают, что скрипты должны стоять в голове, другие — что внизу страницы. А кто-то добавляет асинхронные атрибуты и чувствует себя хакером. Что правда, а что слепое следование старым догмам?
Подключение JavaScript в теге : за и против
Многие начинают с самого очевидного варианта — добавить <script src="script.js"></script> в разделе <head> HTML-страницы, надеясь, что это и есть стандарт. Действительно, браузер тут же встречает скрипт, загружает его, а потом только продолжает читать разметку. На бумаге — всё логично, особенно если код нужен до появления контента (например, для шрифтов или аналитики). Но есть один нюанс, который часто игнорируют даже опытные верстальщики: когда скрипт встречается в <head>, браузер останавливает рендеринг, пока скрипт не подгрузится и не выполнится. Если файл тяжёлый или медленно грузится сеть — пользователи увидят пустой экран вместо сайта. Не самое классное впечатление, правда?
Однако жизнь не чёрно-белая. Иногда без скрипта в <head> просто не обойтись. Вот пара жизненных кейсов:
- Критически важный JavaScript, который управляет работой CSS или шрифтов еще до отображения страницы (например, чтобы избежать "мигания" невидимого текста — FOUT/FILC).
- Системы аналитики, счётчики или скрипты для compliance, которые должны стартовать ещё до загрузки остального контента.
Но вот статистика: по данным HTTP Archive за 2024 год, больше 75% популярных сайтов загружают основные js-файлы не в <head>, а ближе к закрывающемуся </body> — именно для ускорения рендера и улучшения Core Web Vitals. Кстати, если вы вбиваете свой сайт в PageSpeed Insights и видите красные ошибки "Загрузка JavaScript блокирует первичную отрисовку", — скорее всего, дело именно в неправильной позиции подключаемого скрипта.
Что делать? Использовать дополнительные атрибуты: defer
и async
. Вот таблица, чтобы не путаться, как именно работает каждый способ:
Способ подключения | Когда выполняется скрипт? | Блокирует ли рендер? |
---|---|---|
<script src="..."> | Сразу при загрузке | Да |
<script src="..." defer> | После парсинга всего HTML, перед DOMContentLoaded | Нет |
<script src="..." async> | Как только скрипт загружен, не дожидаясь HTML | Нет |
Быстрый совет: если не нужен критический ранний запуск, используйте defer. Так скрипт и загрузится асинхронно, и не будет мешать отрисовке контента.
Ещё интересный факт: Google публично рекомендует использовать defer
для большинства приложений, потому что это гарантирует, что вся DOM-структура уже готова и скрипту не нужно ждать появления элементов на странице через костыли типа window.onload
.

Подключение в конце : старый добрый способ
Есть категория разработчиков, которые вообще игнорируют
— все скрипты лепят прямо перед </body>. В 2010-х это считалось признаком хорошего тона. Почему? Всё просто: браузер сначала парсит и отрисовывает весь контент, а только потом загружает и выполняет скрипты. Это рабочий лайфхак, особенно если вопрос только в пользовательском сторожевом коде — интерфейс загружается почти мгновенно, скрипт не блокирует показ страницы, и пользователь сразу видит нужные блоки.Но если копнуть чуть глубже — появляется пара нюансов. Первое: если у вас несколько скриптов, их порядок важен. Скрипты внизу исполняются строго по очереди, как прописаны в HTML. Второе: если нужно динамически загружать скрипты через JavaScript (например, lazy loading widgets), то приходится городить дополнительные проверки, чтобы не получить гонку состояний.
Есть и третья тонкость — сейчас всё больше разработчиков переходят на single-page application (SPA) или архитектуры вроде React/Vue. При таком подходе, порядок загрузки и исполнение скриптов контролирует сборщик типа Webpack — а подключать голый JavaScript в самом низу страницы становится почти анахронизмом. Но на классических многостраничниках (например, на блогах или landing-page) старый добрый способ всё ещё оправдывает себя.
Ещё пример: когда нужно отправить статистику посещаемости, лучше ставить скрипт повыше (иногда даже в
), а для анимаций, интерфейсных штук — ближе к закрывающему . Это помогает сайту "оживать" быстро, а тяжелые фичи — не мешают первому впечатлению.Кстати, согласно опросу State of Frontend 2024, порядка 63% фронтендеров указывают, что по-прежнему используют подключение скриптов в конце
— хотя признают, чтоdefer
зачастую удобнее и современнее.

Современные подходы и советы: как подключать js сейчас
С каждым годом подключение JavaScript становится проще, но параллельно — появляются и новые нюансы. Вот список советов/лайфхаков, которые я сам использую и однозначно могу рекомендовать:
- Почти всегда используйте
defer
. Это "золотой стандарт" для скриптов, которые должны подхватить готовый DOM, но не блокировать загрузку разметки. - Если скрипт мал, его можно вставлять прямо в HTML (inline), но по стандарту лучше держать отдельные .js-файлы ради кеша и SEO.
- Для сторонних виджетов типа чата — рассмотрите async: пусть грузится, когда получится, не тормозя другие скрипты.
- Следите за порядком: скрипты с
async
могут исполниться в рандомном порядке, а скрипты сdefer
— строго по очереди, как прописано в HTML. - Для современных библиотек, использующих "type="module"", применяйте
defer
по умолчанию — модульные скрипты исполняются только после парсинга HTML. - Не бойтесь использовать lazy loading скриптов: через динамическое добавление тегов
<script>
с помощью JavaScript можно подгружать тяжелые библиотеки только тогда, когда они реально нужны (например, карта в конце страницы или аналитика после согласия на cookies). - Следите за размерами файлов: увеличение весом js-файлов влияет на TTI (Time To Interactive), особенно на мобильных устройствах.
Редкий, но важный совет — если вы всё-таки поддерживаете старые браузеры, учитывайте, что defer
и async
поддерживаются начиная с IE10+. Если у кого-то из клиентов строгие "рекомендации" поддерживать IE9 (где-то в корпоративном аду это ещё требование) — тестируйте с отдельным полифиллом или fallback-скриптом.
Есть ещё фишка: если у вас есть критический JS-код, который нужен сразу — попробуйте разделить логику. Самое "тяжёлое" и второстепенное грузите с defer
или даже через lazy loading, а минимальный startup-код — инлайньте прямо в <head>, но после оптимизации (минификации и tree-shaking).
Ниже шпаргалка для типовых кейсов:
Задача | Рекомендация |
---|---|
Импорт сторонних аналитик | <script src="..." async> в <head> или <body> |
Внешний UI-фреймворк или главный скрипт | <script src="..." defer> в <head> |
Тяжёлый виджет (например, карта или чат) | Динамическая загрузка по событию / видимости |
Мини-код для функционала до загрузки основной страницы | Inline-скрипт в <head> или <body>, только после минификации |
И напоследок: если планируете выходить в топ поисковой выдачи — обратите внимание, что Google любит быстрые сайты. Чем меньше JavaScript блокирует отрисовку, тем лучше ранжирование и выше оценки PageSpeed.
Звучит избито, но: поймите назначение каждого скрипта и ставьте его туда, где он работает оптимально. Часто правильное подключение js-файлов экономит больше времени и нервов, чем даже написание кода. Веб ушёл далеко вперёд, а подход к подключению скриптов стал по-настоящему инженерной задачей.