Ответ
HTTP/2 был разработан для решения проблем производительности, присущих HTTP/1.1. Вот ключевые улучшения:
Мультиплексирование (Multiplexing)
- HTTP/1.1: Страдает от проблемы "Head-of-line blocking". Браузер открывает несколько TCP-соединений (обычно до 6 на домен), но запросы в каждом соединении обрабатываются строго последовательно. Один медленный запрос блокирует все последующие.
- HTTP/2: Позволяет асинхронно отправлять множество запросов и получать ответы в рамках одного TCP-соединения. Это устраняет блокировку и значительно ускоряет загрузку страниц с большим количеством ресурсов (CSS, JS, картинки).
Бинарный протокол (Binary Protocol)
- HTTP/1.1: Текстовый протокол, который легко читать человеку, но он неэффективен и подвержен ошибкам при машинном парсинге.
- HTTP/2: Использует бинарный формат. Он более компактный, его проще и быстрее парсить, он менее склонен к ошибкам.
Сжатие заголовков (Header Compression)
- HTTP/1.1: Заголовки в каждом запросе передаются как обычный текст, часто с большим количеством дублирующейся информации (User-Agent, Cookies).
- HTTP/2: Применяет специальный алгоритм сжатия HPACK, который эффективно кодирует повторяющиеся заголовки, что сильно сокращает объем передаваемых данных.
Приоритезация потоков (Stream Prioritization)
- Клиент может указать браузеру, какие ресурсы важнее (например, CSS-файлы важнее изображений в футере), и сервер будет стараться отправить их в первую очередь.
Server Push
- Сервер может отправлять ресурсы клиенту до того, как тот их запросит. Например, вместе с
index.html
сервер может сразу отправитьstyle.css
, предвидя, что он понадобится клиенту.
- Сервер может отправлять ресурсы клиенту до того, как тот их запросит. Например, вместе с
В Go поддержка HTTP/2 включается "из коробки" при использовании HTTPS:
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// r.Proto покажет "HTTP/2.0", если клиент его поддерживает
w.Write([]byte("Hello, you are using " + r.Proto))
})
// Для работы нужен SSL-сертификат.
// Для локальной разработки cert.pem и key.pem можно сгенерировать самостоятельно.
log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil))
}