ジンジャー研究室

長めのつぶやき。難しいことは書きません。

HTTP/2で再帰的にPUSH_PROMISEするための最速アルゴリズム

話の発端

サーバプッシュするリソースの関連付けを全部手動で書くのが面倒だから、動的に中身を読んで解決したい。 その時に、依存の深いところにあるものでも、リクエストのストリームを閉じずに待たないといけないという制約があった。

jinjor-labo.hatenablog.com

というわけで、依存が深くてもなるべく早くコンテンツを返すためのアルゴリズムを考えた。形式的な説明が思いつかないので具体例を挙げる。

例1

index.htmlがstyle.cssを必要とし、style.cssがback.pngを必要としている。(階層の深さ:2)

index.html

<link rel="stylesheet" href="style.css"></link>

style.css

body { background: url("back.png"); }

最適なレスポンス順序

index.htmlに直接関連するリソース(ここではstyle.css)をPUSH_PROMISEした時点でindex.htmlのコンテンツを返す(この時点ではストリームを閉じない)。それ以上深いリソースのPUSH_PROMISEがすべて終わってからストリームを閉じる。

f:id:jinjor:20150407115139p:plain

back.pngを待たずにindex.htmlの全体を送って良い。なぜなら、ブラウザがindex.htmlをパースしてもback.pngが必要だという情報は得られないから。

例2

index.htmlがstyle.cssとapp.jsを必要としている。(階層の深さ:1)

index.html

<link rel="stylesheet" href="style.css"></link>
...
<script src="app.js"></script>

最適な順序

ストリームで細切れにすればより速い。ブラウザがサブリソースをリクエストしないことを保証したら、その部分のコンテンツを直ちに送りつける。

f:id:jinjor:20150407121006p:plain

まとめ

  • なるべく早くコンテンツを返してブラウザのパースを早める
  • 実装大変そう