Skip to main content

Скрипти в head

1. Як браузер завантажує сторінку

Коли браузер отримує HTML-документ, він виконує такі кроки:

  1. Парсить HTML порядково зверху вниз.
  2. Коли зустрічає тег <link> (CSS), зупиняється і завантажує стиль, тому що стилі впливають на відображення.
  3. Коли зустрічає тег <script>, зупиняє парсинг, щоб виконати JS.

Чому? Тому що скрипт може змінити сам DOM або навіть видалити елементи, які йдуть далі в HTML (document.write, innerHTML тощо). Тому браузер зобов'язаний дочекатися виконання JS, перш ніж продовжити розбір.


2. Що відбувається, якщо script у head

javascript
<head> <script src="main.js"></script> </head> <body> <h1>Привіт!</h1> </body>

По кроках:

  1. Браузер починає читати HTML.
  2. Доходить до <script src="main.js">.
  3. Зупиняє парсинг HTML.
  4. Чекає, поки main.js завантажиться по мережі (може зайняти сотні мілісекунд).
  5. Виконує скрипт.
  6. Тільки потім продовжує парсити решту сторінки.

Увесь цей час:

  • DOM ще не створено,
  • користувач не бачить контенту,
  • метрики FCP / LCP страждають.

3. Проблеми, які це спричиняє

ПроблемаЩо відбувається
Блокується HTML-парсерСторінка не будується, поки не завантажиться JS
Довга "біла сторінка"Користувач бачить порожнечу
Повільні мережі → гірший UXОсобливо на 3G/4G
Погіршення Core Web VitalsLCP, FCP, TTI, TBT - зростають
Скрипти заважають критичним CSSКритичні стилі не застосовуються вчасно

4. Як уникнути блокування

Спосіб 1. defer

javascript
<script src="main.js" defer></script>

Що робить:

  • Скрипт завантажується паралельно з HTML,
  • але виконується лише після повного парсингу DOM (перед DOMContentLoaded).

Без блокування. Гарантований порядок виконання (по черзі). Ідеально для більшості випадків.


Спосіб 2. async

javascript
<script src="analytics.js" async></script>

Що робить:

  • Скрипт завантажується асинхронно (у фоні),
  • і виконується одразу після завантаження, не чекаючи інших.

Використовується для незалежних скриптів (аналітика, реклама, пікселі). Порядок виконання не гарантується.


Спосіб 3. Перенесення скриптів у кінець body

javascript
<body> ... <script src="main.js"></script> </body>

До завантаження JS:

  • HTML повністю розпарсено,
  • користувач уже бачить контент,
  • JS виконується останнім кроком.

Це "старий", але робочий спосіб. У сучасному HTML його замінив <script defer>.


5. Як діяти в продакшені

Тип скриптаДе і як підключати
Основна логіка (UI, SPA)<script src="main.js" defer>
Аналітика, реклама<script src="ga.js" async>
Inline-ініціалізація<script> усередині <head> (маленька ініціалізація)
Старі бібліотекиКраще перенести в кінець <body>

6. Вплив на метрики

МетрикаЩо погіршується при скриптах у head
FCP (First Contentful Paint)Довше показується перший контент
LCP (Largest Contentful Paint)Основний елемент відображається пізніше
TTI (Time to Interactive)JS блокує основний потік
TBT (Total Blocking Time)Зростає через важкі синхронні скрипти

7. Ілюстрація (словами)

javascript
HTML: <head> -> <script> -> <body> ↓ завантаження [======= JS завантажується =======] ↓ виконання [======= JS виконується =======] ↓ тільки потім DOM будується

При defer завантаження йде паралельно, а виконання - наприкінці:

javascript
HTML і JS завантажуються разом → DOM побудовано → JS виконується

Короткий підсумок

СценарійЩо робитьНаслідок
<script> у head без атрибутівБлокує парсингПовільно
<script defer>Завантажує паралельно, виконує після DOMОптимально
<script async>Завантажує і виконує незалежноЛише для незалежних скриптів
<script> унизу bodyЧекає кінця HTMLБез блокування

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.