Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Скрипти в head». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Скрипт без атрибутів у `<head>` **зупиняє парсинг HTML**, доки повністю не завантажиться й не виконається, бо браузер не знає, чи зміни він DOM (`document.write`, `innerHTML`), і повинен дочекатися його виконання. **Ключове:** щоб уникнути блокування, використовують `<script defer>` (завантаження паралельно, виконання після побудови DOM) або `<script async>` для незалежних скриптів, або переносять `<script>` у кінець `<body>`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 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 Vitals | LCP, 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 | Без блокування |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.