Модуль 18

HTTP/2 та оптимізація зʼєднань

Ось урок, згенерований за твоїм майстер-промптом.


🎓 Урок: HTTP/2 та оптимізація з’єднань

(Стиль: CS50 / David Malan)


1. 🔥 Вступ: проблема та мотивація

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

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

У світі веб-розробки це називається Head-of-Line Blocking (блокування початку черги). І саме так працював старий добрий протокол HTTP/1.1, на якому інтернет тримався роками.

Браузер каже серверу: "Дай мені картинку logo.png". І чекає. Поки картинка не завантажиться повністю, він не може попросити "А дай мені ще style.css", використовуючи те саме з'єднання ефективно.

Раніше ми вигадували милиці: об'єднували всі іконки в одну велику картинку (спрайти), зливали всі JS-файли в один гігантський файл, створювали кілька піддоменів (img1.site.com, img2.site.com), аби обманути браузер і відкрити більше "кас".

Але чи не було б краще, якби "каса" була одна, але вона могла б обслуговувати всіх одночасно, перемішуючи товари на стрічці?

Сьогодні ми поговоримо про HTTP/2 — технологію, яка змінила правила гри, дозволивши нам завантажувати сотні файлів одночасно через одне-єдине з'єднання. Навіщо це вам? Щоб ваші сайти літали, а користувачі не закривали вкладку через повільне завантаження.


2. 🧠 Теоретична база (без сухої академічності)

Давайте заглянемо "під капот". Що саме змінилося?

1. Мультиплексування (Multiplexing)

Це найголовніше слово сьогоднішнього уроку. * В HTTP/1.1: Запит -> Відповідь. Наступний Запит -> Наступна Відповідь. Це як односмугова дорога. Якщо їде вантажівка (великий файл), за нею утворюється затор. * В HTTP/2: Ми розбиваємо всі файли на маленькі шматочки (фрейми) і пускаємо їх упереміш по одному з'єднанню. Браузер збирає їх на іншому кінці, як пазл.

Інтуїтивно: Уявіть, що ви завантажуєте 3 картинки. HTTP/2 відправляє шматочок першої, шматочок другої, шматочок третьої, знову шматочок першої... Ніхто нікого не блокує!

2. Бінарний формат замість текстового

HTTP/1.1 був текстовим. Ви могли відкрити консоль і прочитати запит очима (GET / HTTP/1.1). Це зручно для людей, але неефективно для комп'ютерів. HTTP/2 — бінарний. Все перетворюється на одиниці та нулі ще до відправки. Це компактніше, швидше парситься і менше схильне до помилок.

3. Стиснення заголовків (HPACK)

Кожен ваш запит містить купу інформації: User-Agent, Cookies, Accept. В HTTP/1.1 ви відправляли цей текст знову і знову з кожним файлом. Це як вітатися з другом кожного разу, коли ви починаєте нове речення. В HTTP/2 використовується HPACK. Клієнт і сервер запам'ятовують: "Ага, ми вже знаємо, що це Chrome і ось такі куки". Ми передаємо лише те, що змінилося.

4. Server Push (Трохи магії)

Сервер може "передбачити" ваші бажання. Ви просите index.html. Сервер знає, що вам знадобиться style.css, і відправляє його разом з HTML, ще до того, як ви про нього попросили. (Примітка: Ця фіча крута, але складна в налаштуванні, тому зараз її використовують обережно).


3. 🧪 Приклади (від простого до реального)

Приклад 1: "Водоспад" (Waterfall)

Давайте уявимо, як виглядає завантаження сайту з 50 маленькими картинками.

❓ Питання до вас: Як, на вашу думку, виглядатиме графік завантаження в Chrome DevTools для HTTP/1.1?

(Пауза для роздумів)

Відповідь: Це буде схоже на сходинки. Браузер відкриває ~6 з'єднань (ліміт браузера), завантажує 6 картинок, потім наступні 6. Ви побачите багато сірого кольору на графіку (час очікування черги).

А тепер HTTP/2: Всі 50 запитів стартують майже миттєво. Графік виглядає як стіна, що починається в один момент. Картинки з'являються на екрані набагато швидше.

Приклад 2: Реальна конфігурація (Nginx)

Як увімкнути HTTP/2? Ви здивуєтесь, але в коді вам, швидше за все, нічого міняти не треба. Це робиться на рівні веб-сервера.

Ось типовий конфіг Nginx для HTTP/1.1:

server {
    listen 443 ssl;
    server_name example.com;
    ...
}

А ось для HTTP/2:

server {
    listen 443 ssl http2;  # <-- Магія тут!
    server_name example.com;
    ...
}

Пояснення: Ми просто додали прапорець http2. Тепер Nginx знає, як "спілкуватися" по-новому. Важливий нюанс: HTTP/2 у браузерах працює тільки через HTTPS (шифрування). Без SSL сертифіката магії не буде.


4. 🛠 Практична частина

Час перевірити це своїми руками. Відкрийте свій браузер (Chrome/Firefox/Edge).

🔹 Завдання 1: Детектив протоколів 1. Зайдіть на великий сайт (наприклад, Google, Facebook або ваш улюблений новинний портал). 2. Натисніть F12 (Developer Tools) -> вкладка Network. 3. Натисніть правою кнопкою миші на заголовки стовпців (Name, Status...) і додайте стовпець Protocol. 4. Оновіть сторінку (F5). 5. Що ви бачите в колонці Protocol? h2? http/1.1? Може, навіть h3?

🔹 Завдання 2: Наочне порівняння Зайдіть на спеціальне демо (знайдіть у Google "HTTP/2 vs HTTP/1.1 demo" — наприклад, від Akamai або Golang). 1. Запустіть тест для HTTP/1.1. Зафіксуйте час завантаження. 2. Запустіть тест для HTTP/2. 3. Порівняйте візуально, як завантажуються картинки. Відчули різницю?

🔹 Завдання 3: Міні-кейс У вас є сайт інтернет-магазину. На головній сторінці 100 мініатюр товарів. Клієнти скаржаться, що сторінка "гальмує". Ваші дії: * Ви перевірили — картинки оптимізовані, важать мало. * Ви дивитесь в Network і бачите "сходинки" (Waterfall). * Протокол показує http/1.1. * Рішення: Що треба зробити з сервером? (Підказка: див. Приклад 2).

🔹 Завдання 4: А що, якщо... А що, якщо у користувача дуже поганий інтернет з великою втратою пакетів (packet loss)? Подумайте: Якщо ми пускаємо все через одне TCP-з'єднання (HTTP/2), і один пакет загубився... чи не зупиниться вся черга? (Це пастка: так, зупиниться. Це єдиний недолік HTTP/2, який вирішує HTTP/3, але про це пізніше).


5. 💡 Мислення як у розробника

Як змінюється ваше мислення, коли ви переходите на HTTP/2?

❌ Типова помилка новачка: Продовжувати використовувати "милиці" епохи HTTP/1.1. * "Давайте склеїмо всі JS файли в один bundle.js на 5 мегабайт!" * Чому це погано в HTTP/2? Якщо ви зміните один рядок коду, користувач мусить заново качати всі 5 Мб. Краще розбити код на логічні модулі. HTTP/2 завантажить їх паралельно без проблем, а кешування працюватиме ефективніше.

❌ Domain Sharding: Створення img1.cdn.com, img2.cdn.com. * Чому це погано? Кожен новий домен — це нове DNS-запитування, нове TCP-з'єднання, нове TLS-рукостискання. В HTTP/2 це лише гальмує процес. Використовуйте одне з'єднання!

✅ Порада експерта: Завжди налаштовуйте HTTPS. Так, я знаю, на localhost ліньки возитися з сертифікатами. Але пам'ятайте: браузери не підтримують HTTP/2 без шифрування. Якщо хочете тестувати швидкість — ставте сертифікат (наприклад, Let's Encrypt або локальний mkcert).


6. 🧩 Підсумок

Отже, що ми сьогодні розібрали?

  1. Проблема черги: HTTP/1.1 змушував файли чекати один одного.
  2. Рішення: HTTP/2 дозволяє мультиплексування — паралельну передачу даних через одну "трубу".
  3. Бонуси: Стиснення заголовків та бінарний формат економлять трафік.
  4. Вимога: Потрібен HTTPS.

Що ви тепер вмієте? Ви можете відкрити DevTools, перевірити протокол сайту і сказати: "Ага, тут http/1.1, тому воно гальмує. Давайте увімкнемо h2 і приберемо бандлінг картинок!". Ви знаєте, як оптимізувати доставку контенту сучасно.

🔍 Тизер наступного уроку: Ми згадали, що HTTP/2 страждає, якщо мережа втрачає пакети (TCP Head-of-Line Blocking). Чи можемо ми взагалі відмовитися від TCP? Що, якщо побудувати веб на протоколі UDP, який використовують для онлайн-ігор? Наступного разу ми поговоримо про HTTP/3 та протокол QUIC. Це справжня ракета! 🚀

А поки що — це був CS50... тобто, наш урок. До зустрічі!