今回はテキストリソースの圧縮配信を取り上げる。前回のサードパーティタグ は「見えない敵」という意外性があったが、今回はさらに地味だ。コードを一行も書かず、サーバーの設定を変えるだけで効く。しかし実在サイトを調べてみると、この設定が漏れたままのサイトは意外と多い。その多くは単なる設定忘れ、つまりケアレスミスであると思われる。
弊社では 表示速度ボトルネックの実例研究 というブログで、実際のWebページの表示速度のボトルネックを研究している。研究を通して見えてきたのは、GZIP圧縮の有効でないサイトが意外に多いという事実だ。そして圧縮を適用するだけで LCP が1秒以上改善することも珍しくなかった。
テキスト圧縮の仕組み
HTMLやCSS、JavaScriptは人間にも読みやすい形で作られたテキストだ。同じ単語やパターンが何度も繰り返されるため、データ圧縮はてきめんに効く。GZIPはこの繰り返しを検出して短く置き換える。それだけでファイルサイズは大きく縮む。

一般に、テキストリソースは GZIP圧縮で60〜80%のサイズ削減 が期待できる。仮に200KBのJavaScriptファイルが40〜80KBに縮まるとしたら、ダウンロード時間も同じ割合で短くなる。画像はすでに内部で圧縮されているためGZIPを重ねてもほとんど小さくならないが、テキストリソースには大きな効果が出やすい。
GZIPとBrotliの違い
テキスト圧縮には現在 GZIP と Brotli の2方式が広く使われている。
GZIPは歴史が長く(1990年代から使われている)、ほぼすべてのサーバーとブラウザに対応したデファクトスタンダードだ。一方のBrotliはGoogleが開発した比較的新しい方式(2015年公開)で、GZIPより圧縮率が高く、同じファイルでも転送量をさらに15〜20%ほど削減できる。現在の主要ブラウザはBrotliをほぼすべてサポートしている。
どちらも「なし」よりはるかに効果が大きいため、まずGZIPを確実に有効にするのが第一歩だ。CDNやサーバーが対応しているなら、Brotliも合わせて有効にしておくとよい。サーバーはブラウザが Accept-Encoding: br ヘッダーを送ってきた場合のみBrotliで返答し、対応していないブラウザには自動的にGZIPにフォールバックするため、互換性の心配はない。
「テキストは小さいから差は出ない」という誤解
HTML・CSS・JavaScriptのデータ量は、画像や動画に比べれば小さい。だから「圧縮しても大して変わらない」と考えてしまいがちだ。
しかし、ここに落とし穴がある。これらのテキストリソースは、ページ表示のいちばん最初の段階で読み込まれる。HTMLの受信後、CSSやJavaScriptの解析を終えて初めて、ブラウザは描画を始められる。つまりテキストリソースの読み込みは、ページ表示の「スタートダッシュ」そのものだ。
このスタートダッシュが圧縮の有無で遅れると、その遅延は後続のすべての処理にのしかかる。データ量が小さくても、初期段階に乗っているぶん、体感上の遅さへの影響は想像以上に大きい。とりわけHTML・CSS・JavaScriptは、いかに早く読み込みを終えるかが勝負どころだ。これらについては、圧縮してダウンロードを少しでも短く済ませることが欠かせない。
なぜ未圧縮のまま放置されるのか
設定ひとつで効くのに、なぜ圧縮の有効でないサイトがあるのか。理由はおおむね2つに分けられる。
ひとつは、単なる設定忘れ、つまりケアレスミスだろう。多くのWebサーバーは初期状態で圧縮が有効になっている。しかし設定変更の過程で無効のまま引き継がれたり、特定のMIMEタイプが対象から漏れたりする。とくにHTMLは圧縮済みなのにCSS・JavaScriptが対象外というパターンは多い。GZIP設定では対象MIMEタイプを明示的に列挙する必要があり、その列挙漏れがそのまま穴になる。後述するBillboard Japanはまさにこれだ。しかもこの種のミスはサイトの見た目や機能に影響しないため、意識して計測しない限り気づきにくい。開発環境はネットワーク遅延がほぼなく、圧縮の有無で体感差が出ないことも見逃しを助長する。
もうひとつは、過去の名残だ。かつてはデータ圧縮によるサーバーのCPU負荷を嫌い、あえて圧縮しない方針をとるサイトもあった。だが今となっては、これはほとんど意味をなさない。計算機の処理は十分に高速になった。圧縮にかかるCPUコストは今やほぼ無視できる。むしろ大きなデータをネットワークに流すほうが、時間とエネルギーの両面ではるかにコストが高い。CPU負荷を気にして大きなデータを未圧縮で送るのは、まったく割に合わない。テキストリソースを意図的に圧縮しないという選択は、今ではナンセンスと言ってよい。
実在サイトでの実例
弊社の実例研究から、テキスト圧縮の設定漏れが観測されたサイトをいくつか紹介する。以下の数値はすべてシミュレーション結果だ。
京都きもの市場:35件の未圧縮でLCPが1.8秒遅れていた
着物専門ECサイト 京都きもの市場 のトップページでは、HTML 2件、CSS 28件、JavaScript 5件の合計 35件のテキストリソースがGZIP圧縮なしで配信されている状態が観測された。テキストリソースは一般に60〜80%の圧縮率が得られるため、未圧縮のままでは転送データ量が本来の3〜5倍となり、ダウンロード時間に直接影響する。
サードパーティタグの除去や外部CDN依存の解消を経たあとで、このGZIP圧縮を個別に計測した結果が下記だ。
| 指標 | 解消前 | 解消後 | 変化量 |
|---|---|---|---|
LCP | 3.5秒 | 1.7秒 | -1.8秒 |
FCP | 0.8秒 | 0.6秒 | -0.2秒 |
SI | 2.0秒 | 1.7秒 | -0.3秒 |
総合スコア | 91 | 100 | +9 |
GZIP圧縮を適用しただけで LCP が1.8秒短縮され、総合スコア が91から100に到達した。CSS 28件が未圧縮という状況は、スタイルシートが細かく分割されているサイトで起きやすい。サーバー設定の漏れがどれほど大きな影響を与えていたかが、この数値から読み取れる。
詳しいシミュレーション手順は 京都きもの市場のボトルネック研究 にまとめている。
エトヴォス:わずか11件でLCPが1.9秒遅れていた
コスメブランド ETVOS(エトヴォス) の公式オンラインショップでは、CSS 2件、JavaScript 6件、HTML 2件の合計 11件のテキストリソースが未圧縮だった。件数こそ少ないが、他のボトルネックを取り除いたあとで計測すると、その影響は小さくなかった。
| 指標 | 解消前 | 解消後 | 変化量 |
|---|---|---|---|
LCP | 5.8秒 | 3.9秒 | -1.9秒 |
FCP | 1.9秒 | 1.7秒 | -0.2秒 |
SI | 3.3秒 | 2.9秒 | -0.4秒 |
総合スコア | 75 | 86 | +11 |
11件という少ない数でも LCP は1.9秒短縮され、総合スコア は11ポイント上がった。件数の少なさと影響の大きさは比例しない。重要なリソースが未圧縮なだけで、そのダウンロード遅延がクリティカルパスに乗れば指標に直結する。
詳細は エトヴォスのボトルネック研究 を参照してほしい。
RUNWAY channel:44件が未圧縮でFCP・LCP各0.6秒遅れ
複数のレディースファッションブランドを扱うEC RUNWAY channel(ランウェイチャンネル) では、HTML・CSS・JavaScript・JSONを合わせた 44件のテキストリソースがGZIP未圧縮だった。JSON 13件が含まれている点が特徴的で、APIレスポンスや設定データのJSONに圧縮が適用されていないケースは珍しくない。
| 指標 | 解消前 | 解消後 | 変化量 |
|---|---|---|---|
LCP | 3.4秒 | 2.8秒 | -0.6秒 |
FCP | 2.3秒 | 1.7秒 | -0.6秒 |
SI | 2.3秒 | 1.8秒 | -0.5秒 |
総合スコア | 89 | 95 | +6 |
FCP と LCP がそれぞれ0.6秒短縮された。このサイトはサードパーティタグ除去後もいくつかのボトルネックが残っていたが、圧縮の適用はサーバー設定のみで解消できるため、改修コストとして最も低い対処法のひとつだ。
詳細は RUNWAY channelのボトルネック研究 で確認できる。
Billboard Japan:HTMLは圧縮済みでCSS・JSだけ漏れていた
音楽チャート・ニュースサイト Billboard Japan は「圧縮の設定漏れ」の典型例だ。HTMLはすでにGZIP圧縮済みだったが、CSS 12ファイル・JS 22ファイルを含む計35ファイルが未圧縮のまま配信されていた。「圧縮は設定している」という認識のまま、特定のファイルタイプが対象から抜け落ちているパターンだ。
圧縮を適用したときのファイルサイズ変化が顕著だった。CSSは合計215.2KBから35.4KBへ84%削減、JSは425.8KBから107.1KBへ75%削減された。
| 指標 | 解消前 | 解消後 | 変化量 |
|---|---|---|---|
FCP | 0.7秒 | 0.6秒 | -0.1秒 |
LCP | 1.4秒 | 1.2秒 | -0.2秒 |
SI | 1.1秒 | 0.9秒 | -0.2秒 |
このサイトはすでに他の最適化が進んでいた状態での計測のため、指標の変化幅は小さかった。しかしCSSとJSのサイズが7〜8割も削減できていたという事実は大きい。ユーザーの転送量という観点でも無視できない改善だ。「HTMLは圧縮しているからOK」ではなく、CSS・JavaScript・JSONもすべて対象になっているかを確認することが重要だとわかる。
詳細は Billboard Japanのボトルネック研究 に掲載している。
確認方法と対処法
まず圧縮されているか確認する
テキストリソースが圧縮配信されているかは、ブラウザの開発者ツールで確認できる。任意のページを開き、DevToolsの「ネットワーク」タブで対象のCSS・JSファイルをクリックし、レスポンスヘッダーの content-encoding を確認する。
content-encoding: gzipまたは
content-encoding: brと表示されていれば圧縮が有効だ。content-encoding ヘッダー自体が存在しない場合は未圧縮で配信されている。
HTMLだけでなく、CSSとJavaScript、できればJSONやSVGも対象になっているかを確認する。Billboard Japanの例のように、ファイルタイプによって設定が漏れているケースは多い。
Lighthouseの監査結果でも「テキスト圧縮を有効にする(Enable text compression)」という警告が表示される場合もある。Lighthouseを実行して警告がなければ、主要なリソースに対して圧縮は適用されていると考えてよい。
サーバーまたはCDNで有効化する
圧縮の有効化方法はサーバー・CDNの種類によって異なる。代表的な設定例を示す。
Apache(.htaccess または httpd.conf)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json image/svg+xml
</IfModule>nginx(nginx.conf)
gzip on;
gzip_types text/html text/css text/javascript application/javascript application/json image/svg+xml;CloudflareなどのCDN
多くのCDNはSpeed(パフォーマンス)設定から圧縮を有効化できる。CloudflareはデフォルトでBrotliにも対応している。サービスのダッシュボードからSpeed → Optimizationを確認するとよい。
設定変更後は必ずDevToolsで content-encoding ヘッダーを再確認すること。設定を変えたつもりでも、キャッシュやCDNの挙動で即座に反映されないケースもある。
まとめ
- テキストリソース(HTML・CSS・JavaScript・JSON・SVG)はGZIP圧縮で 60〜80%のサイズ削減 が見込める。転送時間が短くなる分、
FCP・LCPの改善につながる。 - 弊社の実例研究では、圧縮を有効にするだけで
LCPが 1.8〜1.9秒 短縮されたサイトが複数あった。件数が少なくても、重要なリソースが未圧縮なら影響は大きい。 - 「HTMLは圧縮している」だけでは不十分だ。CSS・JavaScript・JSONが対象から漏れているケースは多い。全ファイルタイプが対象に設定されているかを確認することが必要だ。
- 確認方法はシンプルで、DevToolsの「ネットワーク」タブで
content-encodingヘッダーを見るだけだ。Lighthouseの警告も参考になる。 - コードの修正は一切不要で、サーバーまたはCDNの設定変更で済む。改修コストが最も低く、効果が大きい手法のひとつ。
サイトに手を入れる前に、まずこの確認から始めてほしい。設定ひとつで指標が動く可能性は十分にある。