ダウンロードが待っているように見えるときは、三つの出来事を切り分けます。応答ヘッダーの到着、本文バイトの到着、アプリケーションが結果を使えるか描画できるか、です。スピナーだけでは、どれが遅れているかは分かりません。

通常のストリーミング段階は重なり合うことがあります。

origin produces a chunk → proxy forwards bytes → client consumes them

プロキシは中継しながら該当する内容をキャッシュに書き込めます。キャッシュにはファイル全体を待つ必要はありません。Squid の read_ahead_gap は配信より先に進む取得を制御するもので、これも別の種類のバッファリングです。

遅いクライアントが出力キューを埋めると、背圧によって上流の読み取りが一時的に止まることがあります。Content-Length も全体をバッファリングせずに長さを伝えます。HTTP/1.1 の chunked 符号化は段階的な配信を可能にしますが、前段の構成要素がデータを保持している場合、低遅延は約束できません。

次に処理段階を調べます。書き換えや検査には本文の一部または全部が必要になる場合があります。圧縮やアプリケーションのフレーミングは有用な出力を遅らせることがあります。クライアント側では、バイト配列全体を待つ方式は返るのが遅くなり、ブラウザは描画できる前にバイトを受け取ることがあります。

CONNECT が成功した後、通常のプロキシはトンネルされたファイルの最終的な長さを知らなくてもサービスのストリームを中継します。バッファーやタイムアウトの設定を変える前に、上の最初の欠けている出来事を追ってください。curl が観測者である場合、その no-buffer オプションはローカルの出力段階を変えます。

関連記事