Якщо ви ще вагаєтеся, чи варто переводити свій веб-проєкт на HTTP/2, відповідь коротка: варто. На прикладі реального проєкту — сайту роздрібної мережі магазинів — показуємо, наскільки швидшим став ресурс після переходу. І що саме доведеться зробити на сервері, щоб отримати той самий результат.
Що дав перехід на реальному проєкті
Ми заміряли середній час завантаження сторінки на одному й тому самому сайті, змінюючи лише протокол доступу. Різниця між найповільнішим і найшвидшим варіантом — понад півтори секунди.
| Доступ через протокол версії | Середній час завантаження сторінки |
|---|---|
| HTTP 1.x без оптимізації | 5,44 с |
| HTTP 1.x з увімкненою оптимізацією: «склеювання файлів», «доменний шардинг» | 5,07 с |
| SPDY/3.1 | 4,77 с |
| HTTP/2 | 3,91 с |
Показово, що класична оптимізація під HTTP 1.1 дала лише 0,37 секунди виграшу, тоді як сама лише зміна протоколу — понад півтори. Тобто впиралися ми не в розмір файлів, а в обмеження самого способу передавання даних.
Як це видно на діаграмах завантаження
На діаграмі завантаження ресурсів (js, css, зображення) для з'єднання HTTP 1.1 чудово видно, що кількість файлів, які завантажуються одночасно, обмежена кількістю потоків, які відкриває браузер. Завантаження відбувається послідовно, і «часова лінія» має значну тривалість. Крім того, з боку сервера теж можуть бути обмеження на кількість потоків для одного браузера. І не забуваймо: усі дані передаються в текстовому вигляді.

На діаграмі для з'єднання HTTP/2 картина зовсім інша. «Часова лінія» коротка, усі ресурси завантажуються паралельно. Якщо переглянути сам потік передавання даних, можна переконатися, що вміст ресурсів іде у двійковому вигляді, а згори застосовується додаткове ZIP-стиснення.

Чому взагалі виникла проблема
За час існування HTTP 1.1 розробники вигадали безліч обхідних прийомів, щоб обійти обмеження протоколу.
- Доменний шардинг — спосіб розподілити безліч файлів між різними доменами та CDN, який розв'язує проблему паралельних з'єднань.
- Спрайти — об'єднання безлічі маленьких зображень в одне велике, щоб пришвидшити завантаження сторінки.
- «Склеювання файлів» — те саме, що спрайти, тільки для коду: усі потрібні CSS і JavaScript об'єднуються в один великий файл, щоб передати його одним потоком по одному з'єднанню.
- Вбудовані технології прискорення в CMS — в окремих системах керування контентом для цього з'являлися власні спеціальні механізми.
Головні відмінності HTTP/2 від HTTP 1.1
Продуктивність
Нова специфікація значно швидша та продуктивніша за HTTP 1.1.
Бінарність
Протокол ефективніший під час парсингу, компактніший у передаванні й менше схильний до помилок.
Мультиплексування
Усі файли підвантажуються паралельно. Запити та відповіді розділяються на фрейми з метаданими, які пов'язують їх між собою, тож вони не перекривають одне одного й не створюють плутанини. Відповіді надходять у міру готовності, тому важкі запити не блокують обробку та видачу простіших об'єктів.
Пріоритизація
Разом із мультиплексуванням з'явилася пріоритизація трафіку: запитам можна призначити пріоритет на основі важливості та залежностей.
Стиснення заголовків
HTTP побудований так, що разом із запитами передаються заголовки з додатковою інформацією, і сервер теж додає заголовки до відповідей. Оскільки сторінка складається з багатьох файлів, заголовки разом дають чималий обсяг. У HTTP/2 вони стискаються, тож допоміжної інформації стає істотно менше, а браузер може надіслати всі запити одразу.
Прогресивність
Усі нові версії популярних вебсерверів уже підтримують протокол.
Шифрування: чому HTTP/2 майже завжди йде разом із TLS
Сам протокол HTTP/2 не вимагає шифрування каналу. Проте всі сучасні браузери працюють із HTTP/2 лише разом із TLS — так само, як і Nginx. Тож масове впровадження протоколу має посприяти поширенню шифрування в мережі.
Через це логіка проста: якщо ви вже використовуєте TLS, варто задіяти HTTP/2, який розкриває весь потенціал шифрування. Під час створення зашифрованого з'єднання відбувається лише один TLS Handshake, а це істотно спрощує весь процес і скорочує час підключення.
Наскільки протокол підтримують браузери
На момент заміру частка версій браузерів із підтримкою HTTP/2 виглядала так.
| Версії браузерів із підтримкою HTTP/2 | Global Market Share |
|---|---|
| IE 11 on Windows 10 | 0,14 % |
| Edge 12, 13 | 0,35 % |
| Firefox 36—45 | 5,09 % |
| Chrome 41—49 | 15,06 % |
| Safari 9 | 0,91 % |
| Opera 28—34 | 0,57 % |
| Safari for iOS 9.1 | 1,07 % |
| Opera 30 for Android | 0,01 % |
| Chrome 46 for Android | 3,59 % |
| Firefox 41 for Android | 0,01 % |
| Разом | 26,79 % |
Решта аудиторії просто продовжує працювати по HTTP 1.1 — протокол узгоджується під час підключення, тож нікого не «відрізає».
Як увімкнути HTTP/2 у себе
- Підключіть SSL-сертифікат. Без TLS сучасні браузери до HTTP/2 не перейдуть, тож починати треба саме з сертифіката.
- Перевірте, що сервер анонсує h2. Зробіть запит до свого домену через openssl s_client із параметром -nextprotoneg. У відповіді має бути рядок на кшталт «Protocols advertised by server: h2, spdy/3.1, http/1.1».
- Увімкніть протокол у Nginx. Потрібна версія 1.9.5 або вище. У файлі конфігурації /etc/nginx/nginx.conf, у секції server, доповніть директиву listen: listen 443 ssl http2; — поряд лишаються server_name, ssl_certificate і ssl_certificate_key.
- Або доповніть конфігурацію Apache. Починаючи з версії 2.4.17, для https-сервера додається Protocols h2 http/1.1, для http-сервера — Protocols h2c http/1.1.
- Вимкніть зайві обхідні прийоми. Склеювання файлів, доменний шардинг та інші хитрощі часів HTTP 1.1 після переходу вже не потрібні.
Що це дає в підсумку
Протокол HTTP/2 значно оптимізованіший порівняно з HTTP 1.1: його впровадження й мінімальні налаштування здатні поліпшити продуктивність вашого веб-проєкту. А вимкнення додаткових хитрощів, які використовували, щоб обійти обмеження HTTP 1.1, може зняти цілий шар бізнес-логіки із системного програмного забезпечення та пришвидшити систему ще більше.
Оптимально налаштувати сервер під ваші навантаження, проконсультувати щодо e-commerce, розібратися, якщо щось пішло не так, — з усім цим краще йти до фахівців. Не вагайтеся й переводьте свої проєкти на HTTP/2.
