HTTP/3と新しいプライオリティ制御方式について

目次

関連記事

HTTP/3については以前書いたとおりです
asnokaze.hatenablog.com

背景

HTTP/2から複数のHTTPリクエストが一つのコネクション上で並列的に送信されるようになりました。それにともない、クライアント側からリクエストの優先度(プライオリティ)をサーバに通知する仕組みが導入されました。

Webページをレンダリングを開始するのに必要なリソース(HTML, CSSなど)の優先度を高く設定したりできます。

現在標準化が進められているHTTP/3でも、最初はHTTP/2と同様、リクエストの依存関係(dependency)と重さ(weight)で優先度を管理する方式(ツリー方式)が検討されていました。

しかし、議論が進むに連れこのツリー方式の優先度制御は複雑であり、あまり実装されていないことがわかりました。(Interimの資料)

HTTP/3では新しい優先度制御方式も議論されましたが、一旦HTTP/3の仕様からは優先度制御の仕組みは外され、優先度制御はオプショナルな機能とする方向となりました。

実際、HTTP/3の仕様からはすでに優先度制御の機能は削除されています。
github.com

またHTTP/2でも優先度制御を行わないで、拡張仕様の優先度制御方式をネゴシエーションする仕組みを検討することになりました。

優先度制御の仕様は、別途デザインチームを結成しそこで議論されることになりました。

ここらへんの議論は、kazuhoさんの記事に書かれているとおりです。
blog.kazuhooku.com

プライオリティの仕様の方向性

HTTP WGのメーリングリストに投げられている通り(URL)、先日行われたQUIC WGの中間会議においてデザインチームのリーダであるIan Sweet氏より、Fastlyのkazuhoさんが提案している「Extensible Prioritization Scheme for HTTP」をベースとして進めていくことがアナウンスされています。

Extensible Prioritization Scheme for HTTP

この仕様では、プロトコルバージョンに依存しない、リクエストここ別に絶対値で示される優先度をもつエンドツーエンドの優先度制御方式を定義しています。

具体的には以下のものが定義されています

  • Priorityヘッダ(リクエスト・レスポンスで使用される)
  • 優先度。urgency (優先度の絶対値)、プログレッシブ
  • ネゴシエーションの仕組み
  • 優先度を更新するフレーム(HTTP/2, HTTP/3の拡張フレーム)
Priorityヘッダ

priorityは下記のような形式です。フォーマットは「Structured Headers」で定義されたDictionary形式です。

   priority = urgency=3, progressive=?1

このヘッダを用いてクライアントはこのHTTPリクエストの優先度をサーバに通知します。

一方で、サーバはレスポンスヘッダにpriorityを指定することで、そのレスポンスがどれくらいの優先度で返されていることを示せます。これによって特に、そのHTTPリクエスト・レスポンスを扱っているProxyに対して、優先度を知らせることができます。

urgency と progressive

priorityヘッダは、urgencyとprogressiveというパラメータを持ちます。

urgencyは-1から6までの値をとります。値が小さいほど優先度が高いです。サーバは優先度が高いものから送信していきます。

  • prerequisite (-1)
  • default (0)
  • supplementary (1~5)
  • background (6)

それぞれ意味次のとおりです。

prerequisite: urgencyがdefaultやprerequisiteのレスポンスを止めます。ブラウザのレンダリングをブロックするようなCSSのリクエストなどに使用されます。

default: 他のリクエストをブロックしません。例えば新しいページに遷移したときにしようされます。

supplementary: この複数要求されたリソースの名から、必須ではないりそーすにつけられます。1~5の値によって優先度がしめされます(クライアントはサーバが上書きして使えるように1,5は使うべきではありません)

background: 他のリクエストに影響が出ないように後回しにできるリクエストに使用される。

ネゴシエーションの仕組み

HTTP/2およびHTTP/2で使用する優先度制御方式をネゴシエーションする方法もこの仕様で定義されています。

SETTINGS_PRIORITIESパラメータを用いてネゴシエーションします。値は次のとおりです

  • 1. H2_TREE: HTTP/2の優先度ツリー方式 (HTTP/3では使用できない)
  • 2. URGENCY: この仕様

また、urgencyとは別にprogressiveを指定できます。progressiveはそのリソースが逐次処理可能なリソースか示します(例えばprogressive jpegなど)。progressiveブーリアンであり0か1をとり、同じurgencyでprogressiveなレスポンスがあった場合は帯域を等分して使います。

優先度の更新

通信中に優先度を更新する場合もあります(例えば、ブラウザのタブを切り替えたり)。そのときに使用する拡張フレームも定義されています。

HTTP/2とHTTP/3両方にPRIORITY_UPDATEフレームを新しく定義しますが、それぞれフォーマットは異なります。HTTP/2ではストリームIDを指定します。HTTP/3ではストリームIDもしくはプッシュIDをしてします。新しい優先度はASCIIでヘッダと同じように指定します。

H2の場合
f:id:ASnoKaze:20191107015351p:plain

H3の場合
f:id:ASnoKaze:20191107015417p:plain