😊

HTTP/2というプロトコルを用いるとネットの通信が速くなる場合があるようで

2021/07/11に公開

HTTP/1.0

HTTPはブラウザ(Webクライアント)とWebサーバ間でデータをどのようにやり取りするかを取り決めたプロトコル。
HTTPにもバージョンがあり、1つのリクエストに対して1つのレスポンスを返す、という形式の通信を取るのがHTTP/1.0(までのバージョン)。筆者がHTTPと聞いてイメージする通信はこれだった。
図に表すとこんな感じ。

上図は、まずはHTMLを、次に画像を、最後にCSSを取得するためのリクエスト/レスポンスが順次生成されている流れとなる。

HTTP/1.1

HTTP/1.0ができた3年後、1999年にHTTP/1.1が生まれる。
もう22年も経つわけだが、現在も尚多くのサーバ-ブラウザ間で使用されているらしい。

HTTP/1.1ではHTTPパイプラインという機能が実現されており、ブラウザから同時に複数のリクエストを出すことができる。図に表すとこんな感じ。

しかしHTTPパイプラインには、「Webサーバはレスポンスをリクエストの順番通りに返さないといけない」というネックがある。上図で言うと、例えばindex.htmlが非常に重たいリソースだと、A.jpgとB.cssのレスポンスもその分遅れてしまう。

この欠点のため、HTTP/1.1を使用しているほとんどのブラウザでは、結局HTTP/1.0と同様にWebサーバに対してリクエストを1つずつ送る通信形態を取っている。

ちなみに上図ではTCPコネクションは1つのていで作成しているが、記事によってはリクエスト/レスポンスごとにコネクションを確立すると説明しているものもあった。この辺はちょっとよく分からないが・・・。

リソースをそれぞれ取得するごとにスリーハンドシェイクするのは悠長だし、おそらくは1ページ表示する上で必要なTCPコネクションは1度で良いのだとは思う。

HTTP/2とは

HTTP/2は複数のリクエスト/レスポンスを並行して処理することができるプロトコル。

1つのコネクションの中でストリームという仮想的なコネクションを複数用意することができ、このストリームの中でリクエスト/レスポンスのやりとりを行う。HTMLのリクエスト/レスポンスはHTMLのストリームで処理され、CSSやJSも然り、という形。

そして各ストリームはそれぞれ独立した存在なので、結果複数のリクエスト/レスポンスを並列して処理することができる。

図にするとこんな感じ。各ストリームを同時に処理している。

またストリームの優先制御が可能なので、HTTPパイプラインと違いどのレスポンスを優先して返すかを規定することができる。この規定はブラウザ側で行う。

例えばリソースの中でも画像などはWebサーバからのダウンロードが完了しきっていなくてもページで表示(レンダリング)され始めるようだが、優先制御を使えば、画像用ストリームの優先度を下げてHTMLなどの必須なリソースをなるべく速く取得するということも可能らしい。

HTML/2.0には他にも、リクエストされていないCSSなどのリソースをサーバーがクライアントに勝手に送信してくれる「サーバープッシュ」機能もある。これによりリクエストの数を減らせるので、ページが表示されるまでの合計通信時間を短縮できる場合があるようだ。

なんか便利なんだろうなとは思いつつ、このサーバープッシュで分からなかったことが1つあった。「Webサーバはどういう基準でリクエストを勝手にブラウザに返すのか」ということ。

おそらくはサーバ側で各リソースの依存関係を決めておいて、依存関係にあるリソースA・BのうちAにだけリクエストが来て、規定した時間Bにリクエストが来なかった場合はBのレスポンスも返す、という仕組みではないかなとは想像したけど、まあちょっとよく分からない。

そもそも並列処理できる上に、優先制御やサーバープッシュの機能もあるため、HTTP/2.0ではそれ以前のHTTPに比べて通信の速度が上がる場合も多いらしい。

だがそれが見込めないケースもあるよう。例えば表示すべきリソースが少ない場合などでは、そもそもサーバへのリクエストの数が少ないので並行処理できてあまり意味がなくなる。

まとめていないまとめ

インターネットの通信を速くするのっていろんなやり方があるんだなと感じた。
HTTP/2については、言い方変かもだけど、大通信(コネクション)の中に小通信(ストリーム)が複数ある、みたいな認識を持った。

参考

Discussion