序章

ハイパーテキスト転送プロトコル(HTTP)は、1989年の発明以来、ワールドワイドウェブ上での通信の事実上の標準となっているアプリケーションプロトコルです。 1997年のHTTP/1.1のリリースから最近まで、プロトコルの改訂はほとんどありませんでした。 しかし、2015年に、HTTP / 2と呼ばれる再考されたバージョンが使用されました。これは、特にモバイルプラットフォームやサーバーを集中的に使用するグラフィックスやビデオを処理する場合に、レイテンシーを減らすためのいくつかの方法を提供しました。 その後、HTTP / 2の人気はますます高まっており、世界のすべてのWebサイトの約3分の1がHTTP/2をサポートしているとの推定もあります。 この変化する状況において、Web開発者は、HTTP/1.1とHTTP/2の技術的な違いを理解することで利益を得ることができ、進化するベストプラクティスについて情報に基づいた効率的な決定を下すことができます。

この記事を読むと、HTTP/1.1とHTTP/2の主な違いを理解し、より効率的なWebプロトコルを実現するためにHTTP/2が採用した技術的な変更に集中できます。

バックグラウンド

HTTP/2がHTTP/1.1に加えた特定の変更をコンテキスト化するために、まず、それぞれの歴史的な発展と基本的な動作を高レベルで見てみましょう。

HTTP / 1.1

HTTPは、ワールドワイドウェブの通信標準として1989年にティモシーバーナーズリーによって開発された、クライアントコンピューターとローカルまたはリモートのウェブサーバーとの間で情報を交換するトップレベルのアプリケーションプロトコルです。 このプロセスでは、クライアントは method を呼び出すことにより、テキストベースのリクエストをサーバーに送信します。 GET また POST. それに応じて、サーバーはHTMLページなどのリソースをクライアントに送り返します。

たとえば、ドメインのWebサイトにアクセスしているとします。 www.example.com. このURLに移動すると、コンピューターのWebブラウザーは、次のようなテキストベースのメッセージの形式でHTTP要求を送信します。

GET /index.html HTTP/1.1
Host: www.example.com

このリクエストは GET 後にリストされているホストサーバーからのデータを要求するメソッド Host:. このリクエストに応えて、 example.com Webサーバーは、HTMLで要求される画像、スタイルシート、またはその他のリソースに加えて、HTMLページを要求元のクライアントに返します。 データの最初の呼び出しですべてのリソースがクライアントに返されるわけではないことに注意してください。 Webブラウザーが、画面にHTMLページのコンテンツをレンダリングするために必要なすべてのリソースを受け取るまで、要求と応答はサーバーとクライアントの間を行き来します。

この要求と応答の交換は、転送層(通常は伝送制御プロトコル(TCP)を使用)の上にあるインターネットプロトコルスタックの単一のアプリケーション層と考えることができます。 )およびネットワーク層(インターネットプロトコルまたはIPを使用):

このスタックの下位レベルについては多くのことを議論する必要がありますが、HTTP / 2の高レベルの理解を得るためには、この抽象化レイヤーモデルとHTTPがその中に含まれる場所を知る必要があるだけです。

このHTTP/1.1の基本的な概要がわからなくなったので、HTTP/2の初期の開発について詳しく説明します。

HTTP / 2

HTTP / 2はSPDYプロトコルとして始まり、圧縮、多重化、優先順位付けなどの手法を使用してWebページの読み込み待ち時間を短縮することを目的として主にGoogleで開発されました。 このプロトコルは、 IETF(インターネット技術特別調査委員会)のハイパーテキスト転送プロトコルワーキンググループhttpbisが標準をまとめたときに、HTTP / 2のテンプレートとして機能し、2015年5月にHTTP/2が公開されました。 当初から、Chrome、Opera、Internet Explorer、Safariなど、多くのブラウザがこの標準化の取り組みをサポートしていました。 このブラウザのサポートもあって、2015年以降、プロトコルの採用率はかなり高く、特に新しいサイトでは高い割合で採用されています。

技術的な観点から、HTTP/1.1とHTTP/2を区別する最も重要な機能の1つは、インターネットプロトコルスタックのアプリケーション層の一部と考えることができるバイナリフレーミング層です。 すべての要求と応答をプレーンテキスト形式で保持するHTTP/1.1とは対照的に、HTTP / 2は、動詞、メソッド、ヘッダーなどのHTTPセマンティクスを維持しながら、バイナリフレーミングレイヤーを使用してすべてのメッセージをバイナリ形式でカプセル化します。 アプリケーションレベルのAPIは、従来のHTTP形式でメッセージを作成しますが、基盤となるレイヤーはこれらのメッセージをバイナリに変換します。 これにより、HTTP / 2より前に作成されたWebアプリケーションが、新しいプロトコルと対話するときに通常どおり機能し続けることができます。

メッセージをバイナリに変換することで、HTTP / 2は、HTTP / 1.1では利用できないデータ配信への新しいアプローチを試すことができます。これは、2つのプロトコルの実際的な違いの根本にある対照です。 次のセクションでは、HTTP / 1.1の配信モデルを見てから、HTTP/2によってどのような新しいモデルが可能になるかを見ていきます。

配信モデル

前のセクションで説明したように、HTTP/1.1とHTTP/2はセマンティクスを共有し、両方のプロトコルでサーバーとクライアント間を移動する要求と応答が、次のような使い慣れた方法を使用して、ヘッダーと本文を含む従来の形式のメッセージとして宛先に到達するようにします。 GETPOST. ただし、HTTP / 1.1はこれらをプレーンテキストメッセージで転送しますが、HTTP / 2はこれらをバイナリにエンコードするため、配信モデルの可能性が大幅に異なります。 このセクションでは、最初にHTTP / 1.1が配信モデルで効率を最適化しようとする方法とこれから生じる問題について簡単に説明し、次にHTTP/2のバイナリフレーミングレイヤーの利点と優先順位について説明します。リクエスト。

HTTP / 1.1 —パイプラインおよびヘッドオブラインブロッキング

クライアントがHTTPで受信する最初の応答 GET 多くの場合、リクエストは完全にレンダリングされたページではありません。 代わりに、要求されたページに必要な追加のリソースへのリンクが含まれています。 クライアントは、ページをダウンロードした後でのみ、ページの完全なレンダリングにサーバーからのこれらの追加リソースが必要であることを発見します。 このため、クライアントはこれらのリソースを取得するために追加のリクエストを行う必要があります。 HTTP / 1.0では、クライアントは新しいリクエストごとにTCP接続を切断して再作成する必要があり、時間とリソースの両方の面でコストがかかりました。

HTTP / 1.1は、永続的な接続とパイプライン化を導入することにより、この問題を処理します。 持続的接続の場合、HTTP / 1.1は、直接閉じるように指示されない限り、TCP接続を開いたままにしておく必要があると想定しています。 これにより、クライアントは、それぞれへの応答を待たずに、同じ接続に沿って複数の要求を送信できるようになり、HTTP/1.0よりもHTTP/1.1のパフォーマンスが大幅に向上します。

残念ながら、この最適化戦略には自然なボトルネックがあります。 同じ宛先に移動する場合、複数のデータパケットが相互に通過できないため、必要なリソースを取得できないキューの先頭にある要求が、その背後にあるすべての要求をブロックする場合があります。 これはヘッドオブライン(HOL)ブロッキングとして知られており、HTTP/1.1での接続効率の最適化に関する重大な問題です。 個別の並列TCP接続を追加すると、この問題を軽減できますが、クライアントとサーバー間で可能な同時TCP接続の数には制限があり、新しい接続ごとに大量のリソースが必要になります。

これらの問題は、前述のバイナリフレーミングレイヤーを使用してこれらの問題を修正することを提案したHTTP / 2開発者の最前線にありました。このトピックについては、次のセクションで詳しく説明します。

HTTP / 2 —バイナリフレーミングレイヤーの利点

HTTP / 2では、バイナリフレーミングレイヤーがリクエスト/レスポンスをエンコードし、それらをより小さな情報パケットに分割して、データ転送の柔軟性を大幅に向上させます。

これがどのように機能するかを詳しく見てみましょう。 HOLブロッキングの影響を減らすために複数のTCP接続を利用する必要があるHTTP/1.1とは対照的に、HTTP/2は2台のマシン間に単一の接続オブジェクトを確立します。 この接続内には、複数のストリームのデータがあります。 各ストリームは、使い慣れた要求/応答形式の複数のメッセージで構成されています。 最後に、これらの各メッセージはフレームと呼ばれる小さな単位に分割されます。

最も詳細なレベルでは、通信チャネルは、それぞれが特定のストリームにタグ付けされた、バイナリエンコードされたフレームの束で構成されます。 識別タグにより、接続は転送中にこれらのフレームをインターリーブし、もう一方の端でそれらを再組み立てできます。 インターリーブされた要求と応答は、背後にあるメッセージをブロックすることなく並行して実行できます。これは、多重化と呼ばれるプロセスです。 多重化は、メッセージが別のメッセージの終了を待つ必要がないようにすることで、HTTP/1.1の行頭ブロッキングの問題を解決します。 これは、サーバーとクライアントが同時に要求と応答を送信できることも意味し、より優れた制御とより効率的な接続管理を可能にします。

多重化により、クライアントは複数のストリームを並列に構築できるため、これらのストリームは単一のTCP接続を使用するだけで済みます。 オリジンごとに単一の持続的接続を持つことで、ネットワーク全体のメモリと処理フットプリントを削減することにより、HTTP/1.1を改善します。 これにより、ネットワークと帯域幅の使用率が向上し、全体的な運用コストが削減されます。

クライアントとサーバーは同じセキュリティで保護されたセッションを複数の要求/応答に再利用できるため、単一のTCP接続によってHTTPSプロトコルのパフォーマンスも向上します。 HTTPSでは、TLSまたはSSLハンドシェイク中に、両方の当事者がセッション全体で単一のキーを使用することに同意します。 接続が切断されると、新しいセッションが開始され、さらに通信するために新しく生成されたキーが必要になります。 したがって、単一の接続を維持すると、HTTPSのパフォーマンスに必要なリソースを大幅に削減できます。 HTTP / 2仕様ではTLSレイヤーの使用が必須ではありませんが、多くの主要なブラウザーはHTTPSを使用したHTTP/2のみをサポートしていることに注意してください。

バイナリフレーミングレイヤーに固有の多重化はHTTP/1.1の特定の問題を解決しますが、同じリソースを待機している複数のストリームがパフォーマンスの問題を引き起こす可能性があります。 HTTP / 2の設計ではこれを考慮に入れていますが、ストリームの優先順位付けを使用することにより、次のセクションで説明するトピックです。

HTTP / 2 —ストリームの優先順位付け

ストリームの優先順位付けは、同じリソースをめぐって競合するリクエストの問題を解決するだけでなく、開発者がリクエストの相対的な重みをカスタマイズして、アプリケーションのパフォーマンスをより最適化できるようにします。 このセクションでは、HTTP / 2のこの機能をどのように活用できるかについてより良い洞察を提供するために、この優先順位付けのプロセスを分解します。

ご存知のように、バイナリフレーミングレイヤーはメッセージをデータの並列ストリームに編成します。 クライアントがサーバーに同時要求を送信する場合、各ストリームに1〜256の重みを割り当てることにより、要求している応答に優先順位を付けることができます。 数値が大きいほど、優先度が高くなります。 これに加えて、クライアントは、依存するストリームのIDを指定することにより、各ストリームの別のストリームへの依存関係も示します。 親識別子を省略した場合、ストリームはルートストリームに依存していると見なされます。 これを次の図に示します。

この図では、チャネルに6つのストリームが含まれており、それぞれに一意のIDがあり、特定の重みに関連付けられています。 ストリーム1には親IDが関連付けられておらず、デフォルトでルートノードに関連付けられています。 他のすべてのストリームには、いくつかの親IDがマークされています。 各ストリームのリソース割り当ては、ストリームが保持する重みと必要な依存関係に基づいて行われます。 たとえば、図では同じ重みと同じ親ストリームが割り当てられているストリーム5と6は、リソース割り当ての優先順位が同じになります。

サーバーはこの情報を使用して依存関係ツリーを作成します。これにより、サーバーはリクエストがデータを取得する順序を決定できます。 前の図のストリームに基づくと、依存関係ツリーは次のようになります。

この依存関係ツリーでは、ストリーム1はルートストリームに依存しており、ルートから派生した他のストリームはないため、使用可能なすべてのリソースが他のストリームよりも先にストリーム1に割り当てられます。 ツリーは、ストリーム2がストリーム1の完了に依存していることを示しているため、ストリーム1のタスクが完了するまでストリーム2は続行されません。 それでは、ストリーム3と4を見てみましょう。 これらのストリームは両方ともストリーム2に依存しています。 ストリーム1の場合と同様に、ストリーム2は、使用可能なすべてのリソースをストリーム3および4よりも先に取得します。 ストリーム2がタスクを完了すると、ストリーム3と4がリソースを取得します。 これらは、重みで示されるように2:4の比率で分割され、ストリーム4のリソースのチャンクが高くなります。 最後に、ストリーム3が終了すると、ストリーム5と6は利用可能なリソースを均等に取得します。 これは、ストリーム4がより多くのリソースを受け取る場合でも、ストリーム4がタスクを完了する前に発生する可能性があります。 下位レベルのストリームは、上位レベルの依存ストリームが終了するとすぐに開始できます。

アプリケーション開発者は、ニーズに基づいてリクエストに重みを設定できます。 たとえば、Webページにサムネイル画像を提供した後、高解像度の画像を読み込むために低い優先度を割り当てることができます。 この重み割り当て機能を提供することにより、HTTP / 2は、開発者がWebページのレンダリングをより適切に制御できるようにします。 このプロトコルを使用すると、クライアントはユーザーの操作に応じて、実行時に依存関係を変更し、重みを再割り当てすることもできます。 ただし、特定のストリームが特定のリソースへのアクセスをブロックされている場合、サーバーが割り当てられた優先度を独自に変更する可能性があることに注意してください。

バッファオーバーフロー

2台のマシン間のTCP接続では、クライアントとサーバーの両方に、まだ処理されていない着信要求を保持するために使用できる一定量のバッファースペースがあります。 これらのバッファは、ダウンストリーム接続とアップストリーム接続の速度が不均一であることに加えて、多数の、または特に大きな要求に対応する柔軟性を提供します。

ただし、バッファが十分でない場合があります。 たとえば、サーバーは、バッファサイズが制限されているか、帯域幅が狭いために、クライアントアプリケーションが処理できないペースで大量のデータをプッシュしている可能性があります。 同様に、クライアントが巨大な画像またはビデオをサーバーにアップロードすると、サーバーバッファーがオーバーフローし、追加のパケットが失われる可能性があります。

バッファオーバーフローを回避するために、フロー制御メカニズムは、送信者が受信者をデータで圧倒するのを防ぐ必要があります。 このセクションでは、HTTP/1.1とHTTP/2がこのメカニズムのさまざまなバージョンを使用して、さまざまな配信モデルに従ってフロー制御を処理する方法の概要を説明します。

HTTP / 1.1

HTTP / 1.1では、フロー制御は基盤となるTCP接続に依存しています。 この接続が開始されると、クライアントとサーバーの両方が、システムのデフォルト設定を使用してバッファサイズを確立します。 受信者のバッファが部分的にデータで満たされている場合、受信者は送信者に受信ウィンドウ、つまりバッファに残っている使用可能なスペースの量を通知します。 この受信ウィンドウは、 ACKパケットと呼ばれる信号でアドバタイズされます。これは、受信者が開始信号を受信したことを確認するために送信するデータパケットです。 このアドバタイズされた受信ウィンドウサイズがゼロの場合、送信者は、クライアントが内部バッファをクリアしてからデータ送信の再開を要求するまで、それ以上データを送信しません。 ここで重要なのは、基盤となるTCP接続に基づいて受信ウィンドウを使用すると、接続の両端でのみフロー制御を実装できるということです。

HTTP / 1.1はバッファオーバーフローを回避するためにトランスポート層に依存しているため、新しいTCP接続ごとに個別のフロー制御メカニズムが必要です。 ただし、HTTP / 2は単一のTCP接続内でストリームを多重化するため、別の方法でフロー制御を実装する必要があります。

HTTP / 2

HTTP / 2は、単一のTCP接続内でデータのストリームを多重化します。 その結果、TCP接続のレベルでの受信ウィンドウは、個々のストリームの配信を規制するのに十分ではありません。 HTTP / 2は、トランスポート層に依存するのではなく、クライアントとサーバーが独自のフロー制御を実装できるようにすることで、この問題を解決します。 アプリケーション層は利用可能なバッファスペースを通信し、クライアントとサーバーが多重化されたストリームのレベルで受信ウィンドウを設定できるようにします。 この微細なフロー制御は、を介した最初の接続後に変更または維持できます。 WINDOW_UPDATE フレーム。

この方法は、アプリケーション層のレベルでデータフローを制御するため、フロー制御メカニズムは、受信ウィンドウを調整する前に、信号が最終的な宛先に到達するのを待つ必要がありません。 中間ノードは、フロー制御設定情報を使用して、独自のリソース割り当てを決定し、それに応じて変更できます。 このようにして、各中間サーバーは独自のカスタムリソース戦略を実装できるため、接続効率が向上します。

フロー制御におけるこの柔軟性は、適切なリソース戦略を作成するときに有利になります。 たとえば、クライアントは画像の最初のスキャンをフェッチしてユーザーに表示し、ユーザーがより重要なリソースをフェッチしながらプレビューできるようにすることができます。 クライアントがこれらの重要なリソースをフェッチすると、ブラウザは画像の残りの部分の取得を再開します。 したがって、フロー制御の実装をクライアントとサーバーに延期すると、Webアプリケーションの知覚パフォーマンスを向上させることができます。

前のセクションで説明したフロー制御とストリームの優先順位付けに関して、HTTP / 2はより詳細なレベルの制御を提供し、より大きな最適化の可能性を開きます。 次のセクションでは、同様の方法で接続を強化できるプロトコルに固有の別の方法、つまり serverpushを使用したリソース要求の予測について説明します。

リソースリクエストの予測

一般的なWebアプリケーションでは、クライアントは GET HTMLのページ(通常はサイトのインデックスページ)を要求して受信します。 インデックスページのコンテンツを調べているときに、クライアントは、ページを完全にレンダリングするために、CSSファイルやJavaScriptファイルなどの追加のリソースをフェッチする必要があることに気付く場合があります。 クライアントは、最初の応答から応答を受け取った後でのみ、これらの追加のリソースが必要であると判断します GET リクエストするため、これらのリソースを取得してページの作成を完了するために追加のリクエストを行う必要があります。 これらの追加の要求により、最終的に接続のロード時間が長くなります。

ただし、この問題には解決策があります。サーバーは、クライアントが追加のファイルを必要とすることを事前に認識しているため、これらのリソースを要求する前にクライアントに送信することで、クライアントの時間を節約できます。 HTTP/1.1とHTTP/2には、これを実現するための異なる戦略があります。それぞれについて、次のセクションで説明します。

HTTP / 1.1 —リソースのインライン化

HTTP / 1.1では、開発者がクライアントマシンがページをレンダリングするために必要な追加のリソースを事前に知っている場合、リソースインライン化と呼ばれる手法を使用して、必要なリソースをHTMLドキュメント内に直接含めることができます。サーバーはイニシャルに応答して送信します GET リクエスト。 たとえば、クライアントがページをレンダリングするために特定のCSSファイルを必要とする場合、そのCSSファイルをインライン化すると、要求する前に必要なリソースがクライアントに提供され、クライアントが送信する必要のある要求の総数が減ります。

ただし、リソースのインライン化にはいくつかの問題があります。 HTMLドキュメントにリソースを含めることは、小さいテキストベースのリソースの実行可能なソリューションですが、非テキスト形式の大きいファイルはHTMLドキュメントのサイズを大幅に増やす可能性があり、最終的に接続速度を低下させ、得られた元の利点を無効にする可能性がありますこのテクニックを使用することから。 また、インライン化されたリソースはHTMLドキュメントから分離されていないため、クライアントが既に持っているリソースを拒否したり、リソースをキャッシュに配置したりするメカニズムはありません。 複数のページでリソースが必要な場合、新しいHTMLドキュメントごとに同じリソースがコードにインライン化されるため、リソースが最初に単にキャッシュされた場合よりもHTMLドキュメントが大きくなり、読み込み時間が長くなります。

したがって、リソースのインライン化の主な欠点は、クライアントがリソースとドキュメントを分離できないことです。 接続を最適化するには、より細かいレベルの制御が必要です。これは、HTTP/2がサーバープッシュに対応しようとする必要性です。

HTTP / 2 —サーバープッシュ

HTTP / 2はクライアントのイニシャルへの複数の同時応答を可能にするため、 GET 要求の場合、サーバーは要求されたHTMLページとともにリソースをクライアントに送信し、クライアントが要求する前にリソースを提供できます。 このプロセスはサーバープッシュと呼ばれます。 このようにして、HTTP / 2接続は、プッシュされたリソースとドキュメントの間の分離を維持しながら、リソースのインライン化という同じ目標を達成できます。 これは、クライアントがメインのHTMLドキュメントとは別に、プッシュされたリソースをキャッシュするか拒否するかを決定できることを意味し、リソースのインライン化の主な欠点を修正します。

HTTP / 2では、このプロセスはサーバーが PUSH_PROMISE リソースをプッシュすることをクライアントに通知するフレーム。 このフレームにはメッセージのヘッダーのみが含まれ、クライアントはサーバーがプッシュするリソースを事前に知ることができます。 すでにリソースがキャッシュされている場合、クライアントは送信することでプッシュを拒否できます RST_STREAM 応答のフレーム。 The PUSH_PROMISE また、frameは、サーバーがプッシュするリソースを認識しているため、クライアントがサーバーに重複した要求を送信するのを防ぎます。

ここで重要なのは、サーバープッシュの重点はクライアント制御であるということです。 クライアントがサーバープッシュの優先度を調整する必要がある場合、またはそれを無効にする必要がある場合は、いつでも送信できます SETTINGS このHTTP/2機能を変更するフレーム。

この機能には多くの可能性がありますが、サーバープッシュがWebアプリケーションを最適化するための答えであるとは限りません。 たとえば、一部のWebブラウザーは、クライアントに既にリソースがキャッシュされている場合でも、プッシュされた要求を常にキャンセルできるとは限りません。 クライアントが誤ってサーバーに重複リソースの送信を許可した場合、サーバープッシュは接続を不必要に使い果たす可能性があります。 最終的に、サーバープッシュは開発者の裁量で使用する必要があります。 サーバープッシュを戦略的に使用してウェブアプリケーションを最適化する方法の詳細については、Googleが開発したPRPLパターンをご覧ください。 サーバープッシュで発生する可能性のある問題の詳細については、JakeArchibaldのブログ投稿HTTP/2プッシュが思ったよりも難しいを参照してください。

圧縮

Webアプリケーションを最適化する一般的な方法は、圧縮アルゴリズムを使用して、クライアントとサーバー間を移動するHTTPメッセージのサイズを縮小することです。 HTTP/1.1とHTTP/2はどちらもこの戦略を使用していますが、前者にはメッセージ全体の圧縮を禁止する実装上の問題があります。 次のセクションでは、これが当てはまる理由と、HTTP/2がソリューションを提供する方法について説明します。

HTTP / 1.1

gzip のようなプログラムは、HTTPメッセージで送信されるデータを圧縮するため、特にCSSファイルとJavaScriptファイルのサイズを小さくするために長い間使用されてきました。 ただし、メッセージのヘッダーコンポーネントは、常にプレーンテキストとして送信されます。 各ヘッダーは非常に小さいですが、この非圧縮データの負担は、要求が増えるにつれて接続にますます重くなります。特に、多くの異なるリソース、したがって多くの異なるリソース要求を必要とする複雑でAPIの多いWebアプリケーションにペナルティを課します。 さらに、Cookieを使用すると、ヘッダーが非常に大きくなることがあり、ある種の圧縮の必要性が高まります。

このボトルネックを解決するために、HTTP / 2はHPACK圧縮を使用してヘッダーのサイズを縮小します。これについては、次のセクションで詳しく説明します。

HTTP / 2

HTTP / 2で何度も登場するテーマの1つは、バイナリフレーミングレイヤーを使用して、より細かい詳細をより細かく制御できることです。 ヘッダー圧縮に関しても同じことが言えます。 HTTP / 2はデータからヘッダーを分割して、ヘッダーフレームとデータフレームを作成できます。 HTTP/2固有の圧縮プログラムHPACKは、このヘッダーフレームを圧縮できます。 このアルゴリズムは、ハフマンコーディングを使用してヘッダーメタデータをエンコードできるため、サイズが大幅に減少します。 さらに、HPACKは、以前に伝達されたメタデータフィールドを追跡し、クライアントとサーバー間で共有される動的に変更されたインデックスに従ってそれらをさらに圧縮できます。 たとえば、次の2つのリクエストを考えてみましょう。

リクエスト#1
method:		GET
scheme:		https
host:		example.com
path:		/academy
accept:		/image/jpeg
user-agent:	Mozilla/5.0 ...
リクエスト#2
method:		GET
scheme:		https
host:		example.com
path:		/academy/images
accept:		/image/jpeg
user-agent:	Mozilla/5.0 ...

これらのリクエストのさまざまなフィールド(次のような) method, scheme, host, accept、 と user-agent、同じ値を持ちます。 のみ path フィールドは異なる値を使用します。 その結果、送信時に Request #2、クライアントはHPACKを使用して、これらの共通フィールドを再構築し、新たにエンコードするために必要なインデックス付きの値のみを送信できます。 path 分野。 結果のヘッダーフレームは次のようになります。

リクエスト#1のヘッダーフレーム
method:		GET
scheme:		https
host:		example.com
path:		/academy
accept:		/image/jpeg
user-agent:	Mozilla/5.0 ...
リクエスト#2のヘッダーフレーム
path:		/academy/images

HTTP / 2は、HPACKおよびその他の圧縮方法を使用して、クライアントサーバーの待ち時間を短縮できるもう1つの機能を提供します。

結論

このポイントバイポイント分析からわかるように、HTTP/2はHTTP/1.1とは多くの点で異なります。一部の機能は、Webアプリケーションのパフォーマンスをより適切に最適化するために使用できるより高いレベルの制御を提供し、その他の機能は単に以前のプロトコル。 2つのプロトコル間のバリエーションについて高レベルの視点を獲得したので、HTTP / 2での多重化、ストリームの優先順位付け、フロー制御、サーバープッシュ、圧縮などの要素がWeb開発の変化する状況にどのように影響するかを検討できます。 。

HTTP/1.1とHTTP/2のパフォーマンスの比較を確認したい場合は、さまざまなレイテンシのプロトコルを比較するこのGoogleデモを確認してください。 コンピューターでテストを実行する場合、ページの読み込み時間は、帯域幅、テスト時に使用可能なクライアントおよびサーバーリソースなど、いくつかの要因によって異なる場合があることに注意してください。 より徹底的なテストの結果を調べたい場合は、記事 HTTP / 2 –実際のパフォーマンステストと分析をご覧ください。 最後に、最新のWebアプリケーションを構築する方法を探求したい場合は、最新のWebアプリケーションを構築してDjangoで顧客情報を管理し、Ubuntu 18.04でReactする方法チュートリアルに従うか、 Ubuntu20.04チュートリアルでHTTP/2サポートを使用してNginxをセットアップする方法を使用した独自のHTTP/2サーバー。