ハイパフォーマンスWebサイトに関する疑問〜パイプラインと並列ダウンロードは同じ意味か?〜

小飼氏のブログで紹介されていた「ハイパフォーマンスWebサイト」。たった14のルールでWebサイトを高速化できると聞いて、読んでみた。

ついに書籍化&邦訳登場 - 書評 - ハイパフォーマンスWebサイト

http://blog.livedoor.jp/dankogai/archives/51030595.html

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

なんて明確なのだろう。オライリーの本って、どこか抽象的で難しい印象があったが、htmlとCSSをかじった程度しかない自分でも、ちゃんと読めば理解できる内容だった。けど、どうしてもわからないところがあった。「パイプラインと並列ダウンロードの違い」である。

パイプライン?並列ダウンロード?

本書では、パイプラインと並列ダウンロードについて、それぞれ以下のような記述がある。

HTTP/1.1で定義されたパイプラインでは、同一ソケット上でレスポンスを待たずに複数のリクエストを送信することが可能になっています。パイプラインを使うと、持続的接続よりもさらに高いパフォーマンスが得られます。しかし残念ながら、パイプラインはInternet Explorer(バージョン7およびそれ以前のバージョンを含む)ではサポートされていません。(ハイパフォーマンスWebサイトP10)

HTTP/1.1では、「ひとつのホスト名に対して並列ダウンロードできるコンポーネント数は2つまで」と制限されています(http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4を参照)。(中略)ガイドラインとして、「ひとつのホスト名に対する並列ダウンロード数は2」ということを覚えておいてください。(ハイパフォーマンスWebサイトP52)

パイプラインにしても、並列ダウンロードにしても、複数のhttpリクエストを同時に送信するという点では同じようだ。ただ、並列ダウンロードには「同時に送信できるhttpリクエストは最大2」という制限があるらしい。パイプラインと並列ダウンロード。この二つは同じ意味なのか?それとも違う意味なのか?もし同じ意味だとしたら、パイプラインにせよ並列ダウンロードにせよ、同時に送信できるhttpリクエスト数は、問答無用で最大2ということになる。もし違う意味だとしたら、並列ダウンロードについては最大2だけれど、パイプラインについては、特に制限無しという話になる。

持続的接続とパイプラインは全く別物。それはわかるけど。。。

このあたりのことは、過去にSlashdotでも議論されているようで、小飼氏の過去のブログで攻防がまとめてあった。しかし、「持続的接続」と「パイプライン」の違いについては書かれているけれど、残念ながら「パイプライン」と「並列ダウンロード」の違いは書かれていなかった。

HTTPサーバーのパイプライン対応

http://blog.livedoor.jp/dankogai/archives/50719947.html

憲法RFC曰く。。。

こんなときは、Webの憲法とでも言うべきRFCを見るのが一番だろう。RFCには、以下のように書かれている。

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4

該当箇所は、「A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.」の部分。問題は、ここで書かれている「connections」とは何かである。「TCPコネクション」なのか、それとも、「httpリクエスト⇔レスポンス」なのか。この解釈の違いで全く異なってくる。

もし、「TCPコネクション」であるとしたら、パイプラインで同時に送信できるhttpリクエスト数には特に制限がないということになる(何発同時にhttpリクエストを送ろうとも、持続的接続をしている限り、TCPコネクションは1回だから。)逆にもし、「httpリクエスト⇔レスポンス」であるとしたら、パイプラインで同時に送信できるhttpリクエスト数は2発までとなる。が、この仕様を読む限りでは、なんとも言いがたい。。。

mozilaで混乱

検索をさらにかけていたら、mozilaのFAQにぶつかった。

How many requests should be pipelined?

Well, pipelining many requests can be costly if the connection closes prematurely because we would have wasted time writing requests to the network, only to have to repeat them on a new connection. Moreover, a longer pipeline can actually cause user-perceived delays if earlier requests take a long time to complete. The HTTP/1.1 spec does not provide any guidelines on the ideal number of requests to pipeline. It does, however, suggest a limit of no more than 2 keep-alive connections per server. Clearly, it depends on the application. A web browser probably doesn't want a very long pipeline for the reasons mentioned above. 2 may be an appropriate value, but this remains to be tested.

http://www.mozilla.org/projects/netlib/http/pipelining-faq.html

ここでさらに混乱。「パイプラインで同時に送信できるhttpリクエスト数は2つが無難」と書いてる。もう、意味がわかりません。

先輩諸氏の意見

こうなったら先輩諸氏の意見を聞くしかない。

こちらのサイトでは、コネクションとは、パイプラインのことではないことを暗に示している。

例えば、先述の「HTML 中に 9 つのインラインイメージを含む Web ページ」があったとして、現在の殆どのブラウザは(パイプラインではなく)複数の HTTP 接続を同時に開き、並列処理で画像を取得するという手法を取っています。

http://www.studyinghttp.net/connections#PracticalConsiderationsForConnections


こちらのサイトでも、同様の意見。

これは、「永続的なコネクションの仕組みを使うときに今まで通りたくさん繋がれると折角の仕組みが逆効果だからやめてくれ」っていう記述であって、したがって "close" なコネクションなら HTTP/1.0 と同様に無制限なんじゃないのかな。もちろん、 HTTP/1.1 のデフォルトとして放っておけば "persistent" なコネクションになるんだから、やっぱり max connections を増やせばこのガイドラインに反する可能性が高いんだけど、しかし、だからといって上の文章を「RFC2616には『同時接続数はhttp/1.1では2 まで』と明確に定められている」と要約することはできないでしょうね。

http://diary.imou.to/~AoiMoe/2006.12/middle.html#2006.12.19_s03

結論。「パイプライン」と「並列ダウンロード」は全く別物。パイプラインの最大同時リクエスト数は特に制限ないけど、4が無難。

どうやら、「パイプライン」と「並列ダウンロード」は全く違う意味ということが、正解の模様。じゃあ、パイプラインは何本でも同時にリクエストしていいのかっていったら、そうでもないみたいだ。こちらのサイトでは、4〜8が無難といっている。

pipeliningに関しては、
・pipeliningは1つの接続で複数のリクエストをやりとりするための手順
・かといってたくさんのリクエストを投げればその分ポートの占有時間も長くなるから迷惑なのは同じ
・だいたい4〜8程度にしておくのが無難。Firefoxは4、Operaは8がデフォルト。

http://www.misao.gr.jp/~koshian/?20061218S2

Firefoxのデフォルトを確認してみた。Firefoxのアドレスバーにabout:configを打ち込んでみると、以下のような設定が出てきた。「connections(接続)」「persistent-connections(持続的接続)」「pipelining(パイプライン)」の三つが明確に区別されており、パイプラインの最大は4になっている。

network.http.max-connections 24
network.http.max-connections-per-server 8
network.http.max-persistent-connections-per-proxy 4
network.http.max-persistent-connections-per-server 2
network.http.pipelining false
network.http.pipelining.maxrequests 4

結論として、「パイプライン」と「並列ダウンロード」は全く別物。パイプラインの最大リクエスト数に特に制限ないけど、とりあえず、4が無難ってところか。Firefoxを高速にしたかったら、pipeliningをtrueにして、pipelining.maxrequestsはデフォルトの4にするのが無難というところだろう。何とか納得。。。

※自分、htmlとcssを若干かじった程度の知識しかないので、間違っていることがあるかもしれません。もし間違いがありましたら、ご容赦くださいますようお願いいたします。