Серед важливих метрик швидкодії сторінки не останнє місце посідають ті, що вказують як швидко користувач побачить щось на екрані при завантаженні вашого документу.
В одному з попередніх дописів ми розглянули, що відбувається, коли HTML-документ потрапляє до бравзера. Серед цих етапів — парсинг і рендеринг. Якщо коротко, то парсинг це перетворення текстового представлення HTML на DOM, а рендеринг — це процес перетворення цієї структури на зображення у вікні переглядача.
І, як виявляється, загальмувати ці процеси надзвичайно просто.
Синхронні скрипти блокують і парсинг і рендеринг. Бравзер має завантажити та виконати ваш скрипт, незалежно від того, що в ньому відбувається, і на цей час обробку документу ставить на павзу.
Чому так? Бравзер припускає, що скрипт може змінити структуру документа. Наприклад, вставити щось через
document.write() чи переписати DOM через innerHTML. Щоправда, нині деякі бравзери вдаються до speculative parsing, продовжуючи "паралельний" парсинг, готуючись до найгіршого, але сподіваючись на краще. І якщо скрипт нічого не змінив в HTML, бравзер використає ці результати парсингу. Але якщо щось його злякає, то він ці результати викине та почне обробляти HTML наново.
Запобігти цьому можна, використовуючи
defer скрипти, які завантажуються в паралелі з парсингом, але виконують лише після завершення парсингу і, що найважливіше — після повної побудови початкового DOM.Стилі ж блокують суто рендеринг. Чим більше у вас підключено різних стилів, чим більшою буде затримка, бо кожен з них бравзер оброблятиме окремо. Це потрібно для того, щоб перед рендером у бравзера вже був готовий CSSOM. З нього він будує Render Tree — і тільки тоді малює сторінку.
Якщо стилів багато — бравзер має завантажити їх усі, обробити й оновити CSSOM. Поки цього не станеться — рендер не почнеться. Завантаження відбувається в паралелі, але рендер не почнеться, доки не буде оброблено всі підключені стилі.
Також, якщо ви використовуєте
@import, ви додаєте ще одну затримку до цього процесу, бо такі імпорти обробляються відкладено.Тут в нагоді стане використання так званого critical path, коли найнеобхідніші стилі, які потрібні для побудови першого відображення, яке дозволяє користувачу вже взаємодіяти зі сторінкою, "вшивають" в сам HTML, тобто додають прямо в
head.І як вишенька на торті — шрифти. Так, шрифти теж блокують рендер, але у свій спосіб — якщо ваш шрифт вантажиться довго, то ви побачите саму сторінку, а от текст на ній не побачите. Це називається FOIT — Flash of Invisible Text.
Зарадити цьому можна в кілька способів. Можна використати
font-display: swap, тоді текст відобразиться системним шрифтом, поки ваш красивий ще вантажиться.Можна зробити передзавантаження шрифту через
<link rel="preload" .../> в head (але без фанатизму). Це не позбавить цієї проблеми повністю, але дозволить суттєво знизити час очікування."Схуднення" файлу шрифта теж, очевидно, допоможе. Прибрати усі непотрібні накреслення, зменшивши таким чином розмір файлу, допоможе прискорити його завантаження.
Найнепопулярніший, але найнадійніший спосіб же — не використовувати зовнішні шрифти. Але кому то цікаво в 2025 році?
🔗 Web Dev: First Contentful Paint
🔗 Web Dev: Render Blocking CSS
🔗 MDN: Optimizing JavaScript downloads
Та й таке. Щось з того практикуєте, чи покладаєтесь на хорошу погоду і стабільний інтернет користувача? Зізнавайтесь.
***
Якщо вам сподобався цей допис, то разом із вогником або серденьком до цього допису додати ще й кілька гривень донату на Mavic для 184 навчального центру. А якщо не сподобався, я це і так зрозумію. Дякую всім і цьом вам у лобіка.
https://send.monobank.ua/jar/AeXQ6YRf2X
5375411202918178
***
@babichdev