Оптимізація Render-Blocking Resources: прискорення FCP і LCP

Повільний рендеринг сторінки втрачає відвідувачів ще до того, як вони побачать контент. Ми усуваємо блокуючі ресурси під ключ: перший екран з'являється помітно швидше, а конверсія зростає. Обговоримо задачу — повернемося з оцінкою та планом.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Оптимізація Render-Blocking Resources: прискорення FCP і LCP
Середній
~2-3 дні
Часті запитання

Render-blocking resources: чому сторінка не віддає перший екран

Браузер будує перший екран строго послідовно: отримав HTML — розібрав розмітку — побудував дерево стилів — порахував розташування блоків — намалював. Будь-який зовнішній ресурс, який трапляється на цьому шляху і вимагає повного завантаження до продовження, зупиняє весь ланцюжок.

Це і є render-blocking resources: таблиці стилів і синхронні скрипти, підключені в <head>, через які користувач бачить білий екран, поки файли летять по мережі.

Механіка різна у двох типів ресурсів, і плутати їх не можна. Зовнішній CSS блокує відрисовку повністю — браузер не покаже жодного пікселя, поки не завантажить і не розбере всі стилі: інакше сторінка мигне неоформленим вмістом.

Синхронний скрипт без async або defer блокує ще раніше — парсер розмітки зупиняється на тезі <script> і чекає завантаження та виконання файлу, а все, що нижче по документу, ще навіть не розібрано.

Критичний шлях завантаження розтягується каскадом. Один скрипт у <head> тягне за собою залежність, та — наступну; поки вони вишиковуються в чергу, перший екран не віддається.

Затримка рендеру складається з часу мережі, розбору та виконання, і кожна зайва зупинка парсера додає до неї повний цикл очікування. Метрики це фіксують напряму: FCP їде вправо, бо перший контент не намальовано, LCP — бо головний елемент екрана з'являється пізніше за всіх інших.

Найгірше те, що блокування маскується під «повільний хостинг» або «важку сторінку». Насправді сервер може віддавати HTML за частки секунди, а користувач все одно дивиться на порожнечу — просто тому, що три файли в <head> вишикувалися в послідовний ланцюжок.

Розбираємо, як це закривається: що виноситься в критичний CSS, що переводиться у відкладене завантаження і як перебудувати порядок ресурсів, щоб перший екран віддавався одразу.

Що дає усунення блокуючих ресурсів

Усунення блокуючих ресурсів переносить відмальовування першого екрана з черги за завантаженням у паралельний потік. Коли стилі та скрипти в <head> перестають тримати парсер, браузер починає будувати розмітку одразу, а не після отримання останнього блокуючого файлу.

На практиці час до першого екрана скорочується в 1,5–3 рази — найсильніше там, де в шапці висіли зовнішні шрифти, синхронні скрипти аналітики та важкі таблиці стилів.

Швидкість віддачі основного контенту зростає не сама по собі, а завдяки пріоритизації: критичний CSS інлайниться в документ, решта підвантажується асинхронно, скрипти отримують defer або async, а некритичні модулі вирушають у відкладене завантаження.

У результаті головний блок із текстом і зображенням з'являється на екрані до того, як довантажиться периферія — користувач бачить контент, а не порожній каркас.

Стабільність метрик — окремий ефект, який помічають не одразу. Поки блокуючі ресурси конкурують за смугу пропускання, показники стрибають: на швидкому з'єднанні все добре, на мобільному мережа віддає документ ривками.

Після розчищення критичного шляху розкид між замірами звужується, і метрики перестають залежати від того, в яку секунду надійшов запит.

Усунений клас затримок — це ланцюжки, де один ресурс чекав на інший: шрифт не завантажувався, поки не виконається скрипт, а скрипт чекав на стилі. Такі послідовності давали найгірші викиди в замірах.

Коли залежності вибудувані паралельно, зі статистики зникають довгі хвости, а не лише середні значення.

Перевіряємо ефект за замірами до і після: час до першого екрана, момент появи основного контенту та розкид метрик під навантаженням. Якщо цифри не рухаються — отже, критичний шлях не розчищений і частина блокуючих ресурсів залишилася в шапці.

Підходи до розблокування критичного шляху

Розблокування критичного шляху — це вибір між кількома техніками, і кожна має свої межі застосування. Нижче — робочі варіанти, які ми комбінуємо під конкретну сторінку, а не застосовуємо «все одразу».

Варіант Коли підходить Обмеження
Критичні стилі inline Перший екран із фіксованою версткою, лендінги, сторінки входу Зростає вага HTML; за частих правок стилів правило потрібно перезбирати
Відкладене завантаження решти CSS Великі каталоги, довгі сторінки з блоками нижче згину Можливий короткочасний «стрибок» стилів, якщо критичний набір неповний
Асинхронні скрипти Лічильники, віджети, чати, усе, що не впливає на перший екран Порядок виконання не гарантований — ламає код із залежностями
Відкладене підвантаження скриптів Важкі модулі: карти, редактори, галереї Потребує явного тригера — прокрутка, клік, простій
Пріоритети завантаження Шрифти, зображення першого екрана, ключові ресурси Помилка в пріоритеті відтягує ресурси, які потрібні раніше

Як обираємо

Спочатку знімаємо замір: які ресурси блокують відрисовку і скільки чекає перший екран. Далі виносимо критичний CSS у розмітку, решту вантажимо відкладено, а скрипти переводимо в асинхронний режим там, де немає залежностей за порядком.

Пріоритети розставляємо в останню чергу — вони підсилюють уже розвантажений шлях, але не замінюють його.

Що це дає

Перший екран відрисовується до підвантаження другорядних ресурсів, а важкі модулі не гальмують показ. На практиці це знімає основну затримку першого контентного показу і прискорює завантаження головного зображення — без переписування логіки застосунку.

Як ми усуваємо render-blocking resources на проєкті

Усуваємо не окремі файли, а порядок, у якому браузер їх отримує. Спершу знімаємо реальну картину завантаження: дивимося водоспад запитів, хто блокує перше відображення, що вантажиться раніше, ніж потрібно, і скільки часу минає до першого контенту та до основного блоку.

Далі вибудовуємо схему пріоритетів — що критично для першого екрана, що можна відкласти, що підвантажити заздалегідь.

  1. Аудит завантаження. Збираємо ланцюжок запитів на реальних сторінках, а не на одній тестовій: головна, каталог, картка, форма. Фіксуємо, які ресурси тримають перше відображення, які підключені в шапці без потреби, де стилі та скрипти заважають одне одному.
  2. Схема пріоритетів. Розкладаємо ресурси на три групи: критичні для першого екрана, другорядні та відкладені. Для кожної групи визначаємо спосіб підключення та момент спрацювання.
  3. Налаштування віддачі. Правки в розмітці та на стороні сервера: критичні стилі віддаємо одразу, решту — асинхронно, зайве знімаємо зі шляху відображення. Налаштовуємо кешування та стиснення, щоб повторні заходи не тягнули те саме заново.
  4. Перевірка в реальних умовах. Вимірюємо метрики на живому трафіку та на різних типах з'єднання, а не лише в лабораторії. Порівнюємо до і після за кожною ключовою сторінкою, окремо дивимося мобільні.
  5. Передача регламентів. Віддаємо команді правила підключення ресурсів і чек-ліст для нових сторінок, щоб порядок завантаження не зламали наступною правкою.

У результаті перше відображення настає помітно раніше, основний контент з'являється без очікування другорядних скриптів, а метрики перестають «плавати» від релізу до релізу. Регламенти фіксують досягнуте — швидкість залишається керованою, а не разовою акцією.

Артефакти: конфігурації, схеми та регламенти

За підсумками робіт ви отримуєте не презентацію, а робочий комплект: файли конфігурацій, схеми пріоритетів завантаження, політики кешування та регламенти супроводу.

Усе це лежить у вашому репозиторії та застосовується без нашої участі — інженерна команда може перевірити кожне рішення за вихідними кодами, а не за описом.

  • Конфігурації віддачі статики: правила роздачі, заголовки керування кешем, налаштування стиснення та версіонування імен файлів — з коментарями, чому обрано саме такий режим.
  • Схема пріоритетів завантаження: які ресурси критичні для першого рендерингу, які завантажуються відкладено, які підключаються на вимогу — з обґрунтуванням для кожного блоку.
  • Політики кешування: терміни життя для статики, розмітки та даних, правила інвалідації під час релізу, щоб оновлення доходило до користувача без ручного очищення.
  • Карта критичного шляху рендерингу: перелік ресурсів, що блокують перший рендеринг і основний контент, із зазначенням, що прибрано, відкладено або вбудовано.
  • Звіт замірів до та після: значення першого рендерингу та рендерингу основного контенту за типами сторінок і умовами мережі, з методикою повторення замірів.
  • Регламент супроводу: як перевіряти метрики після релізів, які пороги вважати деградацією, хто і в якому порядку реагує.
  • Інструкція для розробників: як додавати нові скрипти та стилі, щоб не повернути блокувальне завантаження, з прикладами коректного підключення.
  • Чек-ліст приймання: набір перевірок, за якими ви приймаєте роботу та повторюєте їх самостійно на наступних релізах.

Комплект розрахований на передачу: будь-який інженер, знайомий зі стеком проєкту, відтворює конфігурацію та повторює заміри без звернення до нас. Регламенти описують не разове прискорення, а утримання результату — нові сторінки та правки не відкочують метрики до вихідних значень.

Кейс: як скоротили час до першого екрана втричі

Проєкт — інтернет-магазин із каталогом на десятки тисяч позицій і піковим навантаженням у години розпродажів.

Під час вимірювань на «холодному» кеші час до першого екрана тримався близько 4,2 с, а основний контент з'являвся лише до 6,5 с: у критичний шлях відмальовування потрапляли сторонні скрипти аналітики та віджетів, підключені синхронно в <head>, плюс таблиця стилів усього сайту, яка завантажувалася повністю до першого відмальовування.

Що було до

На кожному переході між розділами каталогу браузер спочатку завантажував і виконував блокуючі ресурси, і лише потім показував хоч щось.

За навантаження в кілька тисяч одночасних сесій картина ускладнювалася: черга запитів зростала, сервер віддавав статику повільніше, і користувачі йшли, не дочекавшись першого екрана. Відмови фіксувалися саме на етапі завантаження, а не на етапі роботи з кошиком.

Що змінили

Ми розібрали критичний шлях відмальовування: винесли стилі першого екрана інлайном, решту відклали; сторонні скрипти перевели в асинхронний режим із відкладеним запуском після першого відмальовування; важкі віджети підвантажували в міру наближення до них під час прокручування.

Додатково налаштували пріоритети завантаження для шрифтів і головного зображення, щоб браузер починав їх завантажувати раніше за інші ресурси.

Метрики до і після

Показник До Після
Час до першого екрана 4,2 с 1,4 с
Поява основного контенту 6,5 с 2,1 с
Блокуючих ресурсів у критичному шляху 9 1
Відмови на етапі завантаження високі знизилися кратно

Роботи вели на високонавантаженому контурі з реальним трафіком, тому ефект перевіряли не на синтетиці, а на живих сесіях. Інструмент контролю — Lighthouse у зв'язці з вимірюваннями на бойовому оточенні.

Чим відрізняється блокування відображення від блокування парсингу?

Блокування парсингу зупиняє розбір HTML: браузер зустрічає синхронний скрипт у <head> і зобов'язаний завантажити та виконати його до того, як продовжить будувати дерево документа.

Поки цього не сталося, далі за розміткою нічого не читається — ні контент, ні стилі, ні картинки. Блокування відображення працює інакше: сторінка вже розібрана, але браузер не малює перший кадр, поки не завантажить і не застосує критичні стилі та шрифти. Тобто парсинг може бути давно завершений, а екран усе ще порожній.

Різниця принципова, бо правки для цих двох випадків різні. Скрипт, який блокує парсинг, лікується атрибутом defer або async — він перестає затримувати побудову документа.

Але якщо той самий скрипт змінює розмітку до першого кадру, defer не допоможе: він виконається після розбору, і користувач побачить мигання контенту.

Точно так само підключення стилів у <head> — це усвідомлене блокування відображення, і прибирати його повністю не можна, інакше отримаєте спалах неоформленої сторінки.

Плутанина призводить до невірних правок: інженер асинхронно підключає все підряд, метрика парсингу покращується, а FCP і LCP стоять на місці або падають.

Або навпаки — вирізає критичні стилі заради «розблокування», і перший кадр малюється голим текстом, після чого сторінка перемальовується. Обидві правки формально зменшують блокування, але б'ють не в ту метрику.

Правильний порядок розбору такий: спочатку дивимося, що саме затримує перший кадр — критичний CSS, веб-шрифт, синхронний скрипт на початку документа.

Потім розділяємо ресурси за роллю: те, що потрібно для першого екрана, залишається блокуючим і інлайниться; усе інше йде в defer або вантажиться після відображення. Після цього перевіряємо, що FCP зсунувся, а не просто зник рядок у звіті аудиту.

Часті технічні сумніви

Прибираємо блокуючі ресурси акуратно: спочатку вимірюємо, потім змінюємо по одному й звіряємо метрики. Нижче — питання, які найчастіше ставлять інженери перед такими правками, і наші відповіді по суті.

Чи не зламає це сумісність зі старими браузерами?

Ні, якщо застосовувати прогресивне покращення. Асинхронне завантаження скриптів, винесення стилів в окремий файл і відкладений розбір некритичного коду підтримуються всіма актуальними рушіями, а для застарілих залишаємо запасний шлях через звичайний тег.

Критичний CSS інлайнимо в розмітку — він застосовується одразу, решта довантажується у фоні. Перевіряємо на реальних пристроях, а не лише в емуляторі.

Чи є ризик, що поїде верстка або логіка сторінки?

Ризик є завжди, тому йдемо покроково: спочатку фіксуємо поточні метрики, потім змінюємо один ресурс і звіряємо відображення та поведінку.

Асинхронні скрипти не повинні залежати від порядку завантаження — якщо залежність є, ставимо атрибути відкладеного виконання та явні обробники готовності. Кожна зміна проходить візуальну звірку та перевірку ключових сценаріїв на стенді до викладення.

Що з наявною розміткою та сторонніми вставками?

Розмітку не переписуємо повністю — точково змінюємо спосіб підключення ресурсів. Сторонні віджети, лічильники та чати виносимо у відкладене завантаження, щоб вони не гальмували перше відображення.

Якщо вставка зобов'язана завантажуватися рано, залишаємо її синхронною, але ізолюємо — вона не повинна блокувати решту сторінки.

Як поводитиметься сторінка під навантаженням?

Передбачувано: менше блокуючих ресурсів — швидше перше відображення, стабільніша реакція при піковому трафіку. Раніше стартує основний контент, нижче навантаження на мережу та пристрій.

Після правок проганяємо навантажувальний тест і дивимося, що час до першого відображення та до завантаження головного контенту тримаються в цільових значеннях.

Опишіть вашу сторінку та поточні метрики — повернемося з оцінкою та планом правок.

Обговоримо ваше завдання і повернемося з оцінкою

Перша розмова — не презентація, а розбір задачі. Нам достатньо адреси стенда або тестового контуру, доступів до репозиторію та системи збірки, а також списку сторінок, де найпомітніше просідають FCP і LCP.

Якщо є звіт Lighthouse або заміри з панелі веб-аналітики — приносьте, але це не обов'язково: базову картину зберемо самі.

Далі дивимося, що саме блокує перше відображення: синхронні скрипти в <head>, стилі без критичної частини, шрифти без font-display, ланцюжки редиректів і сторонні віджети. Окремо перевіряємо, як віддається HTML — статикою, кешем чи кожен запит іде на бекенд.

За підсумками повертаємося з оцінкою та планом робіт:

  • перелік render-blocking ресурсів із зазначенням, який із них тримає FCP, а який — LCP;
  • пріоритети правок: що дає ефект одразу, а що потребує перебудови збірки;
  • варіанти рішення за кожним пунктом з їхнім впливом на решту фронтенду;
  • схему замірів до і після — на яких сторінках і за якими метриками звіряємо результат;
  • ризики: де правка може зачепити аналітику, A/B-тести або сторонні інтеграції;
  • склад робіт, порядок етапів і точки, де потрібна ваша перевірка;
  • відповідальних з обох сторін і формат звітності по ходу робіт.

Щоб оцінка була предметною, від вас потрібні три речі: доступ до середовища, де можна безпечно експериментувати, контакт людини, яка підтвердить пріоритети сторінок, і розуміння, чи є обмеження за строками викату. Цього достатньо, щоб повернутися з планом, а не із загальними словами.

Опишіть задачу — повернемося з оцінкою та планом робіт.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060