HTTP/2 проти HTTP/3: еволюція протоколу
HTTP/2 мультиплексує запити через одне TCP-з'єднання; HTTP/3 замінює TCP на QUIC (Quick UDP Internet Connections) поверх UDP і вирішує проблему блокування на рівні пакетів, яку TCP не може обійти.
Теорія
TL;DR
- HTTP/2 — спільна магістраль: всі машини їдуть паралельно, але одна поламана машина блокує весь потік. HTTP/3 дає кожній машині окрему дорогу.
- Головна різниця: в HTTP/2 залишається HOL-блокування (head-of-line) на рівні TCP-пакетів. HTTP/3 використовує QUIC, де кожен потік відновлюється незалежно.
- На стабільних мережах HTTP/2 і HTTP/3 порівняні. При 3% втраті пакетів HTTP/3 тримає понад 90% пропускної здатності, тоді як HTTP/2 падає на 40%.
- Правило вибору: внутрішня мережа або стабільний LAN → HTTP/2. Мобільний трафік, відеопотоки, глобальний трафік → HTTP/3.
Швидкий приклад
# Перевіряємо протокол сервера
curl -I --http2 https://yourdomain.com
# → HTTP/2 200
curl -I --http3 https://yourdomain.com
# → HTTP/3 200
# У Chrome DevTools: вкладка Network → колонка Protocol
# Шукайте "h2" або "h3"// Node.js: логуємо активний протокол для кожного запиту
app.use((req, res, next) => {
const v = req.httpVersion;
const proto = v >= '3' ? 'h3' : v === '2.0' ? 'h2' : 'h1';
console.log(`${proto}: ${req.path}`);
next();
});
// Вивід: h3: /api/feed (коли HTTP/3 активний)Переговори про протокол відбуваються через ALPN під час TLS handshake. Браузер і сервер домовляються про h2 або h3 ще до першого запиту.
Ключова різниця: HOL-блокування на рівні TCP
HTTP/2 вирішив проблему HOL-блокування HTTP/1.1, запустивши потоки (streams) в одному TCP-з'єднанні. Але TCP гарантує строгий порядок байтів. Якщо один пакет губиться, всі потоки зупиняються в черзі, навіть ті, яких цей пакет не стосується. Це і є TCP packet-level HOL blocking.
HTTP/3 переносить мультиплексування всередину QUIC, який працює поверх UDP. QUIC призначає кожному потоку власне відновлення після втрати. Загублена UDP-датаграма блокує тільки свій потік. Решта продовжує роботу. При 5% втраті пакетів HTTP/2 втрачає близько 40% пропускної здатності, HTTP/3 тримається вище 90%.
Коли що обрати
- Стабільний LAN або корпоративна мережа → HTTP/2. TCP справляється, HOL рідко спрацьовує, налаштування простіше.
- Мобільні користувачі зі змінними мережами → HTTP/3. QUIC відновлюється після втрати пакетів по потоках, а не по всьому з'єднанню.
- Відеопотоки → HTTP/3. YouTube скоротив перебуферизацію на мобільних на 10%, Netflix зменшив час до першого кадру на 25%.
- API з малими пейлоадами → HTTP/2. HPACK-стиснення заголовків дає реальний ефект, а QUIC додає 20% навантаження на CPU на ARM-серверах без відчутного виграшу.
- За Cloudflare або великим CDN → HTTP/3 вже увімкнений за замовчуванням.
- Корпоративні файрволи → HTTP/2 як запасний варіант. UDP 443 часто заблокований, і QUIC автоматично перемикається на h2.
Таблиця порівняння
| Характеристика | HTTP/2 | HTTP/3 |
|---|---|---|
| Транспорт | TCP | QUIC поверх UDP |
| Мультиплексування | Так, потоки в одному TCP | Так, потоки повністю незалежні |
| HOL-блокування | На рівні потоків вирішено, пакетний залишається | Відсутнє - відновлення по потоках |
| Handshake | TCP + TLS (2-3 RTT) | QUIC + TLS 1.3 (1 RTT, 0-RTT при відновленні) |
| Стиснення заголовків | HPACK | QPACK |
| Міграція з'єднання | Ні - прив'язка до IP+порт | Так - Connection ID виживає при зміні мережі |
| Шифрування | Опціональне (TLS) | Обов'язкове (TLS 1.3 вбудований) |
| Підтримка браузерів (2025) | 98% | 92% (Chrome 91+, Firefox 88+, Safari 14+) |
| Навантаження на CPU | Базове | ~20% більше на ARM через QUIC |
| Найкраще для | Стабільні мережі, швидке налаштування | Мобільні, стрімінг, мережі з втратами |
Як це працює всередині
Браузер надсилає розширення ALPN під час TLS handshake зі списком підтримуваних протоколів (h2, h3). Сервер вибирає один і відповідає. Для HTTP/2 Chromium парсить вхідні байти як HPACK-стиснені HEADERS та DATA фрейми, прив'язані до stream ID на TCP-сокеті.
Для HTTP/3 стек переходить на QUIC. Кожен QUIC-пакет містить stream ID. quic::QuicConnection в Chromium обробляє UDP-датаграми та підтверджує кожен потік незалежно через selective ACK, пропускаючи заблоковані потоки замість очікування. Функція 0-RTT кешує ключі шифрування сервера з попередньої сесії, і при повторному підключенні клієнт надсилає HTTP-запит у першому ж пакеті.
Сервер оголошує підтримку HTTP/3 через заголовок Alt-Svc:
Alt-Svc: h3=":443"; ma=86400
Конфіг nginx для одночасного увімкнення обох протоколів:
listen 443 ssl;
http2 on;
http3 on;
ssl_protocols TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400';Типові помилки
Увімкнення HTTP/3 без відкриття UDP 443 на файрволі. QUIC використовує UDP-порт 443. Корпоративні файрволи часто блокують весь UDP. Результат: браузер перемикається на HTTP/2, помилки немає, і ти годинами дивишся чому в DevTools немає h3.
# Відкриваємо UDP 443 на Linux
iptables -A INPUT -p udp --dport 443 -j ACCEPT
# Перевіряємо доступність QUIC
curl --http3 https://yoursite.com
# Якщо бачиш: curl: (92) HTTP/3 not supported
# UDP заблоковано або занадто малий буфер сокета:
sysctl net.core.rmem_max=2500000Плутанина між HPACK і QPACK.
HTTP/2 використовує HPACK зі спільною динамічною таблицею для всіх потоків з'єднання. HTTP/3 використовує QPACK з таблицями на рівні кожного потоку, щоб не відтворювати HOL на рівні стиснення. Якщо перенести HPACK-логіку h2-сервера на h3, отримаєш баги з витісненням записів і потенційне подвоєння розміру заголовків. В nginx явно прописуй http3_qpack_blocks 16384;.
Очікування що QUIC завжди швидший. На стабільних мережах з великою пропускною здатністю QUIC додає CPU-навантаження без приросту throughput. API з малими пейлоадами на добре підключених серверах можуть деградувати. Бенчмаркуй перед переходом.
Ігнорування ризиків 0-RTT replay. QUIC 0-RTT відновлює зашифровану сесію в першому пакеті. Але ці дані може відтворити зловмисник у мережі. Cloudflare обмежує 0-RTT тільки GET-запитами і не застосовує до POST/PUT. Якщо у тебе є GET-ендпоінти зі зміною стану, це важливо врахувати.
Відсутність тесту h2-fallback в навантажувальних тестах. Близько 8% користувачів ще не мають підтримки HTTP/3. Якщо навантажувальний тест запускається тільки через Chrome з h3, ти не бачиш патерни h2-трафіку, включно з TCP HOL-спайками при перевантаженні.
Де зустрічається в реальних проектах
- Cloudflare маршрутизує 80% трафіку через HTTP/3, включно з бекендами Discord-ботів.
- YouTube використовує h3 на мобільних і скоротив перебуферизацію приблизно на 10%.
- Netflix доставляє відеочанки через h3 і зменшив медіанний час до першого кадру на 25%, відкривши реалізацію як
quic-go. - Next.js 14+ визначає активний протокол для streaming SSR-відповідей.
- Deno Deploy використовує HTTP/3 за замовчуванням для всіх edge-деплоїв.
Питання на співбесіді
Q: Що таке HOL-блокування (head-of-line blocking) в HTTP/2 та HTTP/3?
A: В HTTP/2 втрачений TCP-пакет зупиняє всі потоки на з'єднанні, доки TCP не повторить передачу. В HTTP/3 QUIC відновлює втрати по потоках, тому зупиняється тільки постраждалий потік.
Q: Як QUIC-handshake перевершує TCP + TLS?
A: TCP потребує тристоронньої схеми перед стартом TLS. QUIC поєднує транспортний і крипто-обмін в один раунд: 1 RTT для нових з'єднань, 0-RTT для відновлення де ключі кешовані з попередньої сесії.
Q: Що таке QPACK і навіщо він потрібен в HTTP/3 замість HPACK?
A: HPACK використовує спільну динамічну таблицю для всіх потоків. В HTTP/3 потоки незалежні, тому спільна таблиця відтворила б HOL на рівні стиснення заголовків. QPACK тримає таблиці per-stream щоб цього уникнути.
Q: Що відбувається коли корпоративний файрвол блокує UDP 443?
A: Браузер пробує QUIC, отримує відмову і автоматично перемикається на HTTP/2 через TCP. Користувач не бачить помилки, в логах немає h3-трафіку. Перевіряй заголовок Alt-Svc і доступність UDP через Wireshark (фільтр: quic).
Q (senior): При 5% втраті пакетів — яка різниця у throughput між HTTP/2 і HTTP/3 кількісно?
A: За даними дослідження Google QUIC, HTTP/2 втрачає близько 40% throughput через TCP tail-loss і таймаути перепередачі. HTTP/3 з QUIC selective ACK тримає понад 90%. Різниця: TCP блокує ціле з'єднання на одній втраті, QUIC відновлюється локально в потоці.
Приклади
Вплив HOL-блокування на паралельні запити
Найпростіший спосіб побачити блокування в дії — Chrome DevTools з мережевим throttling на 3G.
// 10 паралельних запитів до ресурсів
// HTTP/2: всі зупиняться якщо TCP втратить пакет
// HTTP/3: тільки постраждалий потік призупиниться
const urls = Array.from({ length: 10 }, (_, i) => `/api/item/${i}`);
const start = performance.now();
const results = await Promise.all(
urls.map(url => fetch(url).then(r => r.json()))
);
console.log(`Усі 10 завантажено за ${(performance.now() - start).toFixed(0)}ms`);
// При 1% втраті пакетів (throttling у DevTools):
// HTTP/2: ~4500ms (TCP HOL спрацьовує)
// HTTP/3: ~2800ms (потоки відновлюються незалежно)Стеж за колонкою Protocol у DevTools. Запити з міткою h3 завершуються більш рівномірно порівняно з h2 в умовах слабкого сигналу.
Міграція з'єднання в QUIC
Ця функція найбільше важлива для мобільних застосунків, але їй приділяють найменше уваги.
// HTTP/2 (TCP): при перемиканні WiFi на 4G змінюється IP
// TCP-з'єднання прив'язане до IP+порт: новий handshake, новий TLS, ~500ms затримка
// HTTP/3 (QUIC): використовує Connection ID, а не IP+порт
// При зміні мережі QUIC-сесія продовжується з тим самим ID
// Connection ID: abc123
// WiFi: 192.168.1.5:443 → З'єднання: abc123
// 4G: 10.0.0.15:443 → З'єднання: abc123 (та сама сесія, без повторного handshake)
// Для відеозастосунку: відтворення не переривається
// коли користувач виходить із зони WiFiЯ бачив на практиці як це спричиняє непомітні баги з токенами авторизації прив'язаними до IP: сервер бачить той самий Connection ID, але нову IP-адресу, і деякий auth-middleware позначає це як спробу перехоплення сесії. Перевір що робить твій middleware зі зміною IP перед тим як вмикати QUIC в продакшені.
Числа продуктивності по сценаріях втрати пакетів
Втрата пакетів 0%:
HTTP/2: ~2500ms
HTTP/3: ~2300ms (мінімальний приріст)
Втрата пакетів 1%:
HTTP/2: ~4500ms (TCP HOL починає впливати)
HTTP/3: ~2800ms (QUIC відновлюється по потоках)
Втрата пакетів 3% (типове перевантаження 3G/4G):
HTTP/2: ~8500ms
HTTP/3: ~3500ms (в 2.4 рази швидше)Ці цифри з контрольованих навантажувальних тестів. Реальні результати залежать від відстані до сервера і CDN-ноди, але закономірність зберігається: перевага HTTP/3 зростає зі збільшенням втрат пакетів і зникає на чистих мережах.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.