ファイルサイズ削減による高速化の効果
回線高速化による高速化の収穫逓減
2020年6月29日
著者: 竹洞 陽一郎
よくWebサイトの高速化で語られるのは、HTML、CSS、JavaScript、画像のファイルサイズの削減です。
例えば、画像を最適化する、画質を落とす、Gzip圧縮するなどの方法で、ファイルサイズを減らす事が有効という主張をインターネット上で見ます。
実際のところ、ファイルサイズを小さくすることで、Webパフォーマンスの高速化にどの程度寄与するでしょうか?
伝送速度
1秒間にどの位のデータを送る事ができるのかを、伝送速度(Transmission rate)と云います。
日常会話では通信速度と云ったりしますが、国際規格としてはビットレート(Bit rate)と云います。
これは、単位時間あたりの通信できるbit数を表したものです。
しかし、日常、私達が使うファイルサイズの単位はbitではなく、byteです。
ですから、bit単位で表記されている数値は、byteに換算する必要があります。
例えば、100Mbpsの伝送速度は、100,000,000bit ÷ 8 = 12,500,000 byte = 12.5MBです。
💡ここがポイント!
古くからコンピュータを使っていた人にとっては、「え、1024と2進数で割って計算するんじゃないの?」と思われるでしょう。
国際単位系では、10進数を使う事が規格として定められており、1KB=1000byte、1MB=1000KBとなります。
2進数を使う場合には、IEC80000-13に従い、1KiB(キビバイト)=1024byte、1MiB(メビバイト)=1024KBという表記となります。
同様に、bpsについても、1Mbpsは、1024Kbpsではなく、1000Kbpsとなります。
1024Kbpsの意味にしたい場合は、1Mibpsと記載します。
伝送速度はネットワークに限らず、CPU、メモリ、PCI Express、GPU、SSD、NIC(ネットワークカード)など、PCを構成する各種デバイス間のデータ転送量にも使う言葉です。
伝送速度は、スループットとも呼ばれます。
ダウンロードの前処理
HTTP/HTTPSでWebブラウザがWebサーバと通信して、HTMLやCSS、JavaScript、画像をダウンロードする時間は、基本的には、前処理に必要な時間とファイルサイズで決まります。
ここで言う前処理とは、TCPとSSLの接続確立の手続きです。
- DNS Lookup
- URLのドメイン名やホスト名から、通信する対象のIPアドレスを得る。国内でDNSサーバを構築すると5~10ms程度で処理できるが、クラウドサービスなどを使うと、遅いサービスだと100ms以上掛かる。
- TCP Connection
- 通信先のIPアドレスとの間に、TCP 3way handshakesの処理を行い、通信経路を確立する。通常は2~3ms程度で処理できる。
- SSL Handshakes
- SSL(正しくはTLS)を使って通信する場合に、鍵の交換処理を行う。OSCP(Online Certificate Status Protocol)の処理時間もここに含まれる。速ければ10ms程度、遅いと300msぐらい掛かる。
前処理は凡そ20~50msぐらい掛かります。
そして、GETリクエストや、POSTリクエストは1ms以下で送信されます。
Webページの場合、まずはHTMLが送出され、ここはWebサーバの性能や混雑度合い、静的HTMLページか、動的HTMLページかで時間が変わります。
💡ここがポイント!
HTMLがWebブラウザに到達するまでの時間は、以上から50~100msぐらいの範疇に収まると理想的です。
HTML、CSS、JavaScriptのパース処理
HTMLがダウンロードされると、Webブラウザでパース(parse:構文解析)という処理が行われます。
Webブラウザのパース処理は、以下の3つの処理があります。
- HTMLのタグを解釈して文書構造を構築
- CSSを解釈して文書構造に表示処理を適用
- JavaScriptのコードを解釈してコンパイルし実行
この構文解析処理ですが、HTMLの書き方、CSSの書き方、JavaScriptの書き方など、コーディングスキルに大きく影響されます。
コーディングスキルが高い人は、以下の点を考慮します。
- HTMLのパースが一気通貫で終わるようにする
- CSSのパースがRight To Leftであり、要素毎の総当たり処理となることを考慮して、入れ子にしない、単純化する
- JavaScriptの読込をasyncやdefer、もしくはWeb workerを使った別スレッド化して、HTML、CSSのパースを分断しないようにし、画像のダウンロードにできるだけ影響を及ぼさないようにする
依存関係で変わるパース処理時間
プログラムの処理では、依存関係という言葉が出てきます。
例えば、AというプログラムがBというプログラムの機能を利用して、Aの実行の前にBの読込や実行が必要であると、AとBの間に依存関係があると云います。
Webブラウザの処理でも、このような依存関係はあります。
HTMLのパース処理で、CSSが読み込まれて、CSSを解釈して表示処理を適用するわけですから、HTMLのパース処理とCSSのパース処理には密接な依存関係があります。
これにJavaScriptが入ってくると、この依存関係は、複雑になります。
例えば、Webページにカルーセルを入れるとどうなるでしょうか?
HTMLのパースで、カルーセルの箇所のDOM Treeが構築され、そこの領域をCSSで表示の定義を行い、且つJavaScriptで画像を自動スライドさせるようにすると、画像のダウンロードの前に、HTML、CSS、JavaScriptのパース・実行処理が絡みます。
見た目のダウンロード時間と真のダウンロード時間
WebページのWarterfall図を見るときに、この知識がないと、見た目のダウンロード時間で判断を誤ります。
次のWarterfallの枠で囲った箇所の画像は、ダウンロードに433ms掛かっています。
ちなみに、画像のサイズは、2MBあります。
普通に考えれば、「2MBの画像なんだから、容量を削減すべき」と思うでしょう。
しかし、容量を小さくしても、あまり高速化に寄与しません。
この画像をオブジェクト計測してみましょう。
オブジェクト計測とは、画像などを、それだけダウンロードする計測です。
HTMLやCSS、JavaScriptのパース処理が絡まないため、ファイル単体の純粋なダウンロード時間を計測できます。
このデータを見ると、DNS LookupからSSLまでの前処理を除いた、純粋なダウンロード時間は114msです。
パース処理が絡んだダウンロード時間 | パース処理が絡まないダウンロード時間 | 差分 |
---|---|---|
433ms | 114ms | 319ms |
💡ここがポイント!
この差分の319msが、パース処理との依存関係によるオーバーヘッドです。
具体的に、どんな処理が絡んでいるのでしょうか?
それは、Chrome Developer Toolsなどのプロファイリングツールで確認可能です。
ダウンロードに影響している処理を知る
遅延している画像をクリックして、Call Treeのタブをクリックします。
この例では、各種JavaScriptの処理が絡んでいる事が分かります。
💡ここがポイント!
このような画像は、decoding="async"でバックグラウンドダウンロードを実行したり、loding="lazy"で遅延読込をしても、JavaScriptとの依存関係があるため無効化されます。
実際に時間を消費しているボトルネック(この場合はJavaScriptの処理)を、どうにか解決しない事には、この画像については、高速化しないのです。
この処理の合計は、きっかり319msにはなりません。
計測ごとにバラツキが生じますし、計測の環境で異なるからです。
しかし、どのような依存関係があり、どの程度、時間を消費しているのか、上記のような手法で内訳を把握できます。
スループットとファイルサイズによるダウンロード時間
では、前処理や依存関係を除いて、純粋にファイルサイズだけで、どの位、ダウンロード時間は変わるのでしょうか?
以下の表に纏めました。
スループット | ||||||||
---|---|---|---|---|---|---|---|---|
3Gの実質速度 | 4Gの実質速度 | 4.5Gの実質速度 | 5Gの実質速度 | |||||
ファイルの容量 | 5Mbps | 10Mbps | 30Mbps | 50Mbps | 100Mbps | 200Mbps | 1Gbps | 4Gbps |
100KB | 0.16秒 | 0.08秒 | 0.0267秒 | 0.016秒 | 0.008秒 | 0.004秒 | 0.0008秒 | 0.0002秒 |
300KB | 0.48秒 | 0.24秒 | 0.08秒 | 0.048秒 | 0.024秒 | 0.012秒 | 0.0024秒 | 0.0006秒 |
500KB | 0.8秒 | 0.4秒 | 0.1333秒 | 0.08秒 | 0.04秒 | 0.02秒 | 0.004秒 | 0.001秒 |
1MB | 1.6秒 | 0.8秒 | 0.2667秒 | 0.16秒 | 0.08秒 | 0.04秒 | 0.008秒 | 0.002秒 |
3MB | 4.8秒 | 2.4秒 | 0.8秒 | 0.48秒 | 0.24秒 | 0.12秒 | 0.024秒 | 0.006秒 |
5MB | 8秒 | 4秒 | 1.3333秒 | 0.8秒 | 0.4秒 | 0.2秒 | 0.04秒 | 0.01秒 |
10MB | 16秒 | 8秒 | 2.6667秒 | 1.6秒 | 0.8秒 | 0.4秒 | 0.08秒 | 0.02秒 |
現在、日本の携帯網は、4.5Gと5Gが並行して整備されています。
4.5Gは、5Gの本格的な普及までの過渡期を担う高速携帯網です。
地方でも、100Mbps以上のスループットが出る場所がどんどん増えています。
英国のモバイルの調査会社Opensignalが発表した「モバイル・ネットワーク・ユーザー体感レポート Japan2020年4月」によると、日本における携帯3社の4G利用時間は97.8~99%と高い率であることが分かります。
そして、日本におけるダウンロード速度は、40Mbpsを超えている事が分かります。
では、30Mbpsのところを見て、ファイルサイズの変化でどれだけダウンロード時間が短縮できるのかを見てみましょう。
これは、ファイルが合体しているか、個々に分かれているかは、ほぼ影響がありません。
HTTP/1.1でKeep-Alive有効の場合には、TCPの通信が確立したら、ファイルが分かれていても、前処理無しに、一連のダウンロードとして処理されるからです。
- 10MB ... 2.66秒
- 5MB ... 1.33秒
- 3MB ... 0.8秒
- 1MB ... 0.26秒
- 500KB ... 0.13秒
- 300KB ... 0.08秒
- 100KB ... 0.02秒
この数値は、理論値であり、実際はもう少し遅くなります。
特に、スマートフォンは、CPUの性能がダウンロード時間に大きな影響を受けます。
また、インターネットの中は、バケツリレーの世界ですから、経路のどこかのネットワーク機器が遅延すると、その影響で遅延します。
この数値から、ファイルサイズの縮小を行うと、3MBぐらいまでは効果が大きいものの、そこから先は、実際の効果は小さくなっていく、収穫逓減となっています。
そして、2021年には、日本全国で4.5Gの普及し、100Mbpsが普通となっているでしょうから、更に、高速化の効果が無くなっているでしょう。
💡ここがポイント!
HTTP/2は、TCPコネクションを1本しか利用しないため、ファイルが待ち行列に入って、HTTP/1.1より遅延します。
依存関係を綺麗に解消すると、その差は一目瞭然です。
下記の2つのWarterfall図は、依存関係を解消した画像のダウンロードのHTTP/1.1とHTTP/2の比較です。
HTML、CSS、JavaScriptをminifyしたり、Gzip圧縮してファイルサイズを削減する価値が殆ど無いのも、上述の回線の高速化に伴う、効果の収穫逓減が原因です。
むしろ、これらのファイルは、サイズより、中のコードの記述量と、その複雑さの方が大きな遅延要因となります。
同じ本をハードカバーで持ち歩くか、文庫本で持ち歩くかで、重さは異なるのですが、中に書いてある文章は同じですから、読み終えるのに必要な時間はほぼ変わらないのと同じです。
💡ここがポイント!
従来の通信回線のスループットを前提として行われてきた、ファイルサイズを主たる変数とするWebパフォーマンスの高速化は、もう今後は通用しないという事です。
この点こそが、現在、CDN各社や携帯回線各社が打ち出しているEdge Computingサービスの存在理由です。
今後は、パフォーマンスエンジニアリングの主流である、計算処理の分離・分散・高速化こそが、Webパフォーマンスチューニングの本流となるのです。
「5Gが普及すれば、Webパフォーマンスは気にしなくて良くなる」と仰る方がいます。
残念ながら、通信速度が高速化すれば、データのやり取りは増える一方で、それがフロントエンド、もしくはバックエンドの計算量を増加させます。
そして、人は、スピードが上がるほどに、それが当たり前と感じ、慣れてしまい、更なるスピードを要求するのです。
それは、CPUがどんなに高速化しても、OSの体感速度が殆ど変わらないのと同じです。
PC上での計算量が増え続けている事と、人の感覚が速さに慣れてしまっている事が原因で、これと同じ道をWebパフォーマンスも辿っていくのです。
そして、スーパーコンピュータの世界ランキングで1位になった「富岳」に代表されるように、速さを追い求め続けるのは、計算機科学の本質的な命題でもあります。