Какие основные преимущества HTTP/2 перед HTTP/1.1?

Ответ

HTTP/2 был разработан для решения проблем производительности, присущих HTTP/1.1. Вот ключевые улучшения:

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

    • HTTP/1.1: Страдает от проблемы "Head-of-line blocking". Браузер открывает несколько TCP-соединений (обычно до 6 на домен), но запросы в каждом соединении обрабатываются строго последовательно. Один медленный запрос блокирует все последующие.
    • HTTP/2: Позволяет асинхронно отправлять множество запросов и получать ответы в рамках одного TCP-соединения. Это устраняет блокировку и значительно ускоряет загрузку страниц с большим количеством ресурсов (CSS, JS, картинки).
  2. Бинарный протокол (Binary Protocol)

    • HTTP/1.1: Текстовый протокол, который легко читать человеку, но он неэффективен и подвержен ошибкам при машинном парсинге.
    • HTTP/2: Использует бинарный формат. Он более компактный, его проще и быстрее парсить, он менее склонен к ошибкам.
  3. Сжатие заголовков (Header Compression)

    • HTTP/1.1: Заголовки в каждом запросе передаются как обычный текст, часто с большим количеством дублирующейся информации (User-Agent, Cookies).
    • HTTP/2: Применяет специальный алгоритм сжатия HPACK, который эффективно кодирует повторяющиеся заголовки, что сильно сокращает объем передаваемых данных.
  4. Приоритезация потоков (Stream Prioritization)

    • Клиент может указать браузеру, какие ресурсы важнее (например, CSS-файлы важнее изображений в футере), и сервер будет стараться отправить их в первую очередь.
  5. 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))
}