HTTP/2で再帰的にPUSH_PROMISEするための最速アルゴリズム
話の発端
サーバプッシュするリソースの関連付けを全部手動で書くのが面倒だから、動的に中身を読んで解決したい。 その時に、依存の深いところにあるものでも、リクエストのストリームを閉じずに待たないといけないという制約があった。
というわけで、依存が深くてもなるべく早くコンテンツを返すためのアルゴリズムを考えた。形式的な説明が思いつかないので具体例を挙げる。
例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がすべて終わってからストリームを閉じる。
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>
最適な順序
ストリームで細切れにすればより速い。ブラウザがサブリソースをリクエストしないことを保証したら、その部分のコンテンツを直ちに送りつける。
まとめ
- なるべく早くコンテンツを返してブラウザのパースを早める
- 実装大変そう