Мінімізація HTTP-запитів
Мінімізація HTTP-запитів потрібна тому, що кожен запит коштує окремого з'єднання, мережевої затримки та навантаження на сервер, а не лише переданих байтів. Чим менше запитів робить сторінка, тим швидше браузер доходить до рендеру і тим кращими виходять метрики LCP, FCP і TTFB.
Теорія
TL;DR
- Кожен запит це DNS-резолвінг, TCP-з'єднання, TLS-рукостискання і аж потім передача даних.
- Навіть дрібний файл на 5 KB коштує десятків або сотень мілісекунд затримки, і ці затримки додаються.
- CSS і JS блокують рендер, тому зайві запити відкладають появу контенту для користувача.
- Прийоми: бандлінг і мініфікація, спрайти,
srcsetтаimage-set(), HTTP/2 і HTTP/3, кешування і CDN, lazy loading, inlining критичного CSS. - Виграш: швидший First Paint, нижчий TTI, кращі Core Web Vitals і SEO.
Швидкий приклад
Погано, 7 HTTP-запитів лише заради CSS і JS:
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="grid.css">
<link rel="stylesheet" href="header.css">
<link rel="stylesheet" href="footer.css">
<script src="jquery.js"></script>
<script src="slider.js"></script>
<script src="form.js"></script>Краще, 2 запити замість 7, файли об'єднані та мініфіковані:
<link rel="stylesheet" href="bundle.min.css">
<script src="bundle.min.js" defer></script>Що відбувається під час кожного запиту
Коли браузер іде по новий ресурс (CSS, JS або зображення), він щоразу проходить повний цикл:
- DNS-резолвінг: знайти IP-адресу домену.
- TCP-з'єднання: рукостискання клієнта і сервера.
- TLS-шифрування (якщо HTTPS): ще одне рукостискання.
- Запит і відповідь: лише тепер дані починають вантажитися.
Навіть якщо ресурс крихітний, ці етапи займають десятки або сотні мілісекунд. А якщо таких файлів сотні, затримка підсумовується.
Чому це сповільнює сайт
| Проблема | Що відбувається |
|---|---|
| Довгі мережеві затримки | Поки вантажаться всі файли, рендер відкладається |
| Блокуючі ресурси | CSS і JS блокують показ контенту |
| Навантаження на CPU і пам'ять | Браузеру треба обробити багато файлів |
| Більше з'єднань, більше енергії | Особливо критично на мобільних |
| Падіння Core Web Vitals | LCP, FID, TBT, CLS погіршуються |
Як зменшити кількість HTTP-запитів
1. Бандлінг і мініфікація. Об'єднуйте CSS і JS (Webpack, Vite, Rollup, esbuild; Next.js робить це сам). Мініфікація прибирає пробіли і скорочує імена змінних.
2. Спрайти для іконок. SVG-спрайт або один PNG-спрайт замість десятків дрібних зображень. У CSS потрібний фрагмент вирізається через background-position.
3. image-set() і srcset. Замість завантаження всіх розмірів картинки браузер бере лише той, що потрібен під конкретний екран.
4. HTTP/2 і HTTP/3. Ці протоколи вміють мультиплексувати кілька файлів через одне з'єднання. Але навіть із ними менше запитів означає менше заголовків і менше оверхеду.
5. Кешування і CDN. Заголовки Cache-Control, ETag, Last-Modified дають браузеру право не робити новий запит, поки ресурс не змінився.
6. Lazy loading. Вантажте зображення, відео і JS лише тоді, коли вони справді потрібні.
7. Inlining. Критичний CSS або дрібний SVG можна вставити прямо в HTML (<style> або <svg>). Це особливо важливо для контенту above the fold.
Цифри для орієнтиру
| Тип ресурсу | Середня вага | Вплив на завантаження |
|---|---|---|
| CSS/JS | 30-500 KB | Блокують рендер |
| Зображення | 100-1000 KB | Довге завантаження |
| Шрифти | 30-150 KB | Можуть спричинити Flash of Invisible Text |
| API-запити | 100-500 ms затримки | Затримка контенту |
Навіть 10-20 дрібних файлів по 5 KB здатні сповільнити сторінку на сотні мілісекунд, просто через мережеві затримки.
Результат оптимізації
Після мінімізації запитів:
- швидший перший рендер (First Paint);
- нижчий Time to Interactive (TTI);
- менше блокуючих ресурсів;
- кращі SEO і Core Web Vitals;
- користувачеві здається, що сайт «летить».
| Причина | Навіщо мінімізувати |
|---|---|
| Менше мережевих затримок | Швидше завантаження сторінки |
| Менше оверхеду | Менше CPU і пам'яті |
| Краще на мобільних | Менше витрат батареї і трафіку |
| Кращий SEO | Google вище ранжує швидкі сайти |
| Кращий UX | Користувач бачить контент раніше |
Типові помилки
- Вважати, що HTTP/2 скасував проблему. Мультиплексування прибирає чергу з'єднань, але не прибирає заголовки, пріоритезацію і роботу браузера з кожним окремим ресурсом.
- Зліпити все в один гігантський бандл. Один файл на 3 MB блокує рендер гірше, ніж кілька розумно розбитих чанків із code splitting.
- Інлайнити все підряд. Вбудований у HTML ресурс не кешується окремо, тож інлайнять лише критичний мінімум.
- Забувати про заголовки кешу. Без
Cache-Controlбраузер щоразу йде на сервер, навіть якщо файл не змінився. - Оптимізувати лише статику. Десяток дрібних API-запитів на старті сторінки коштує не менше, ніж десяток зображень.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.