How many bytes did I read?

フルリロード、差分リロードした際に読み込んだバイト数を記録しているのだが、これは実は概算であって正確な値ではない。というのは意外なことに javascript から実際に読み込んだバイト数を得る方法はけっこう限られている。特に、レスポンスボディが圧縮されているとそれが顕著になる。

まずレスポンスヘッダ内の Content-Length があれば、それが読み込んだバイト数となる。終わり。圧縮されている場合は圧縮されている状態の転送バイト数となる。ふたばのサーバでは、html ファイルを読み込むと gzip 圧縮されたものが Content-Length 付きで返ってくる。しかし、差分リロードした際のリクエスト(これも gzip 圧縮されている)には Content-Length はない。したがって差分リロードの際に何バイト読み込んだかは全くわからない。

次に XMLHttpRequest の progress イベントをリスンすると、loaded プロパティと total プロパティで転送バイト数が得られる。ただし、内容が圧縮されている場合はこのイベントは少なくとも Chrome ではあまり役に立たない。全体を読み込み終えたあとで 1 回だけ発生し、その際 total は 0、loaded は展開後のバイト数が格納されている。つまり、圧縮状態の転送バイト数は読み取れない。

また、ここまではレスポンスボディの話だったがレスポンスヘッダのサイズも javascript からは正確なその値を取得できない。XMLHttpRequest#getAllResponseHeaders() が返す値は微妙に加工されている(HTTP/1.1 云々のラインなど)。加えて書くと、プロトコルが HTTP/2 の場合はヘッダも圧縮されているのでなおのこと実際に転送されたバイト数はわからない。

ということで差分リロードの際の転送バイト数および https 上の各読み込み時のヘッダに関してはヒューリスティックな謎の係数を使って圧縮後のサイズを概算しているのであった。これがだいたいの場合だいたい合ってるようなのだが合わないときは盛大に合わない。

さてどうしたものか。

Leave a Reply

Your email address will not be published. Required fields are marked *