Skip to content
33 / 41

Что такое HTTP/2 мультиплексирование?


Полный ответ

Сравнение HTTP/1.1 и HTTP/2:

JavaScript
HTTP/1.1 (6 соединений, запросы последовательны в каждом):

Соединение 1: [--- style.css ---][--- logo.png ---]
Соединение 2: [--- app.js ------][--- font.woff2 -]
Соединение 3: [--- vendor.js ---]
Соединение 4: [--- hero.jpg ----]
Соединение 5: [--- analytics.js ]
Соединение 6: [--- icons.svg ---]

HTTP/2 (1 соединение, всё параллельно через потоки):

Соединение:
Stream 1: [frame][frame]      [frame]           = style.css
Stream 3:    [frame][frame][frame]               = app.js
Stream 5:       [frame]   [frame][frame]         = vendor.js
Stream 7: [frame]      [frame]         [frame]   = hero.jpg
Stream 9:          [frame][frame]                 = logo.png
...все чередуются в одном TCP-соединении

Структура HTTP/2:

JavaScript
HTTP/2 соединение
|
|-- Stream 1 (запрос/ответ для style.css)
|  |-- HEADERS frame (запрос)
|  |-- HEADERS frame (ответ)
|  |-- DATA frame (часть тела)
|  |-- DATA frame (часть тела)
|
|-- Stream 3 (запрос/ответ для app.js)
|  |-- HEADERS frame
|  |-- DATA frame
|  |-- DATA frame
|  |-- DATA frame
|
|-- Stream 5 (запрос/ответ для hero.jpg)
|-- HEADERS frame
|-- DATA frame
|-- ...

Проверка HTTP/2 в браузере:

JavaScript
// Через Resource Timing API
const resources = performance.getEntriesByType('resource');

for (const res of resources) {
  console.log(`${res.name}: ${res.nextHopProtocol}`);
  // "h2" -- HTTP/2
  // "h3" -- HTTP/3
  // "http/1.1" -- HTTP/1.1
}

// Проверка для текущей страницы
const [nav] = performance.getEntriesByType('navigation');
console.log(`Страница загружена по: ${nav.nextHopProtocol}`);

Что это значит для разработчика:

JavaScript
// В HTTP/1.1 делали так (domain sharding -- антипаттерн для HTTP/2):

// ❌ Распределяли ресурсы по доменам для обхода лимита соединений
// <img src="https:// img1.example.com/photo1.jpg">
// <img src="https:// img2.example.com/photo2.jpg">
// <img src="https:// img3.example.com/photo3.jpg">

// Каждый домен -- отдельные 6 соединений

// ✅ При HTTP/2 все ресурсы с одного домена -- через один коннект
// <img src="https:// cdn.example.com/photo1.jpg">
// <img src="https:// cdn.example.com/photo2.jpg">
// <img src="https:// cdn.example.com/photo3.jpg">

// Один домен, одно соединение, все параллельно

JavaScript
// HTTP/1.1 антипаттерн: объединение файлов в спрайты и мега-бандлы

// ❌ Раньше: один огромный bundle.js (всё в одном, чтобы один запрос)

// При HTTP/2 это вредит, потому что:
// 1. Изменение одного модуля инвалидирует весь кеш
// 2. Пользователь грузит ненужный код

// ✅ С HTTP/2: гранулярные чанки
// vendor.js, auth.js, dashboard.js, profile.js

// Параллельная загрузка, лучшее кеширование

Настройка HTTP/2 на сервере:

Nginx

# nginx -- HTTP/2 включается одной директивой
server {
    listen 443 ssl http2;
    # HTTP/2 требует TLS (технически не обязательно, но все браузеры требуют)

    ssl_certificate     /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;

    # Увеличение лимитов потоков
    http2_max_concurrent_streams 128;   # по умолчанию 128
}

📌 Реальные кейсы

Влияние мультиплексирования на загрузку:

JavaScript
Страница с 50 ресурсами:

HTTP/1.1 (6 параллельных соединений):
Раунд 1: 6 ресурсов параллельно
Раунд 2: 6 ресурсов параллельно
...
Раунд 9: 2 ресурса (остаток)
Итого: ~9 раундов, каждый ждёт самый медленный ресурс в группе

HTTP/2 (1 соединение, все параллельно):
Все 50 запросов отправлены одновременно
Ответы приходят по мере готовности
Нет блокировки одного запроса другим (на уровне HTTP)
Итого: общее время определяется самым медленным ресурсом

Когда мультиплексирование не помогает:

JavaScript
1. Если сервер отдаёт ресурсы последовательно (однопоточный бэкенд)
2. Если TCP-окно слишком маленькое (slow start на новом соединении)
3. При потере TCP-пакета ВСЕ потоки блокируются (TCP Head-of-Line Blocking)
Эту проблему решает HTTP/3 (QUIC поверх UDP)

Резюме

Мультиплексирование -- главное улучшение HTTP/2. Одно TCP-соединение вместо 6-8, все запросы параллельно, нет очередей. Это делает бессмысленными хаки вроде domain sharding и CSS-спрайтов. Но TCP Head-of-Line Blocking остаётся проблемой -- её решает HTTP/3 (QUIC).

Что такое HTTP/2 мультиплексирование? | JScriptiser