ナビゲーションをスキップ
部 IV 章 22

圧縮

序章

ユーザーの時間は貴重なので、ウェブページの読み込みに長時間待たされることはないはずです。HTTPプロトコルはレスポンスを圧縮することができ、コンテンツの転送に必要な時間を短縮できます。圧縮は、多くの場合、ユーザー体験の大幅な向上につながります。ページの重さを減らし、Webパフォーマンスを向上させ、検索順位を上げることができるのです。そのため、検索エンジン最適化の重要な一部となっています。

この章では、HTTPレスポンスに適用されるロスレス圧縮について説明します。画像、音声、動画などの media フォーマットで使用される非可逆圧縮と可逆圧縮は、ページの読み込み速度を上げるために(それ以上に)同様に重要です。しかし、これらは通常、ファイル形式自体の一部であるため、この章の範囲ではありません。

HTTP圧縮を使用するコンテンツタイプ

HTTP圧縮は、HTMLCSSJavaScript、JSON、SVGなどのテキストベースのコンテンツや、woff, ttf, ico ファイルに対して推奨されています。画像のようなすでに圧縮されているメディアファイルは、前述のようにその表現にすでに内部圧縮が含まれているため、HTTP圧縮の恩恵を受けることはありません。

図22.1. コンテンツの種類に応じた圧縮方法

他のタイプのコンテンツと比較すると、text/plaintext/html はもっとも圧縮率が低く、12%と14%しか圧縮を使用していない。これは、動的に生成されたコンテンツも圧縮することが良い影響を与えるにもかかわらず、text/htmlがJavaScriptやCSSなどの静的コンテンツよりも動的に生成されることが多いためかもしれません。JavaScriptコンテンツの圧縮に関する詳しい分析は、JavaScriptの章にあります。

HTTP圧縮のためのサーバー設定

HTTPのコンテンツエンコーディングについては、HTTP規格で Accept-Encodingリクエストヘッダーが定義されており、HTTPクライアントは、どのコンテンツエンコーディングを扱えるかをサーバーに通知できます。サーバーの応答には、応答本文のデータを変換するためにどのエンコーディングが選ばれたかを指定する Content-Encoding ヘッダーフィールドを含めることができます。

実質的にすべてのテキスト圧縮は、2つのHTTPコンテンツエンコーディングのうちの1つによって行われます。GzipBrotliです。BrotliとGzipの両方は、事実上すべてのブラウザでサポートされています。サーバー側では、nginxやApacheなどもっとも普及しているサーバーでBrotliやGzipを使用するように設定できます。この設定は、コンテンツが生成されるタイミングによって異なります。

  • 静的コンテンツ:このコンテンツはあらかじめ圧縮しておくことができます。ウェブサーバーは、ファイル名の拡張子などに基づいて、URLを適切な圧縮ファイルにマップするように設定できます。たとえば、CSSやJavaScriptは静的コンテンツであることが多いので、あらかじめ圧縮しておくと、Webサーバーがリクエストごとに圧縮する手間を省くことができます。
  • 動的に生成されるコンテンツ:これは、ウェブサーバー(またはプラグイン)自身がリクエストごとにその場で圧縮する必要があります。たとえば、HTMLやJSONは、場合によっては動的コンテンツになり得ます。

BrotliまたはGzipでテキストを圧縮する場合、異なる圧縮レベルを選択することが可能です。圧縮レベルを高くすると、圧縮ファイルは小さくなりますが、圧縮に時間がかかります。解凍中、CPU使用率は重く圧縮されたファイルほど高くならない傾向があります。むしろ、高い圧縮レベルで圧縮されたファイルは、デコードが若干速くなります。

使用するWebサーバーソフトによっては、圧縮を有効にする必要があり、あらかじめ圧縮されたコンテンツと動的に圧縮されたコンテンツとで設定が、分かれる場合があります。Apacheでは、Brotliは mod_brotli で、Gzipは mod_deflate で有効にすることができるようになっています。nginxでは、Brotliを有効にする方法、Gzipを有効にする 方法も公開されています。

HTTP圧縮の動向

下のグラフは、過去3年間のHTTP Archiveメトリクスによるロスレス圧縮の使用率シェアの推移を示したものです。2019年からBrotliの利用率が2倍に、Gzipの利用率が若干減少しており、全体的にデスクトップ、モバイルでHTTP圧縮の利用率が伸びていることがわかります。

図22.2. デスクトップでの圧縮方法の傾向。
図22.3. モバイル向け圧縮方式の動向。

圧縮されて提供されているリソースのうち、大多数はGzip (66%) またはBrotli (33%) を使用しています。その他の圧縮アルゴリズムが使用されることはほとんどありません。この割合は、デスクトップとモバイルでほぼ同じです。

図22.4. HTTPレスポンスの圧縮アルゴリズム。

ファーストパーティとサードパーティの圧縮

サードパーティーは、ウェブサイトのユーザー体験に影響を与えます。歴史的に、サードパーティーと比較してファーストパーティーが使用する圧縮の量は大きく異なっていました。

デスクトップ モバイル
コンテンツエンコーディング ファーストパーティ サードパーティ ファーストパーティ サードパーティ
テキスト圧縮なし 58.0% 57.5% 56.1% 58.3%
Gzip 28.1% 28.4% 29.1% 28.1%
Brotli 13.9% 14.1% 14.9% 13.7%
Deflate 0.0% 0.0% 0.0% 0.0%
その他/無効 0.0% 0.0% 0.0% 0.0%
図22.5. デバイスタイプ別のファーストパーティ製とサードパーティ製の圧縮率。

この結果から、2020年との比較では、ファーストパーティコンテンツがサードパーティコンテンツに圧縮の利用で追いつき、同等の方法で圧縮を使っていることが分かります。圧縮、とくにBrotliの利用が両カテゴリーで伸びている。Brotliの圧縮率は、ファーストパーティコンテンツにおいて、1年前と比較して2倍になっています。

圧縮レベル

圧縮レベルとは、エンコーダーに与えられるパラメーターで、入力の冗長性を見つけるための努力の量を調整し、結果として高い圧縮密度を達成するために使われます。圧縮レベルが高くなると圧縮速度が遅くなりますが、伸長速度にはあまり影響がなく、むしろ若干速くなります。圧縮前のコンテンツの場合、圧縮に要する時間は事前に設定できるため、ユーザー体験に影響を与えることはない。動的コンテンツの場合、CPUがリソースを圧縮するのに必要な時間は、圧縮されたデータをネットワーク経由で送信する速度向上とトレードオフできる。

Brotliエンコーディングは0から11の圧縮レベルを許容し、Gzipは1から9のレベルを使用します。Zopfliのようなツールを使えば、Gzipでもより高いレベルを達成することができる。これは下のグラフで opt として示されている。

HTTPアーカイブの summary_response_bodies データテーブルを使用して、現在ウェブで使用されている圧縮レベルを分析しました。これは異なる圧縮レベル設定でレスポンスを再圧縮し、もっとも近い実際のサイズを取ることで、Brotliを使用した約14,000の圧縮レスポンスと、Gzipを使用した約11,000の圧縮レスポンスを基に推定しています。

各レベルのインスタンス数をプロットすると、もっともよく使われるBrotli圧縮レベルについて、圧縮レベル5付近と最大圧縮レベルの2つのピークが、あることがわかる。4以下の圧縮レベルの使用はまれです。

図22.6. Brotliの圧縮レベル。

Gzip圧縮は、圧縮レベル6を中心に、レベル9まで適用されます。レベル1にピークがあるのは、人気のあるWebサーバーnginxのデフォルト圧縮レベルであるためと思われます。比較のため、Gzipレベル9は何千もの冗長性マッチングを試み、レベル6はそれを約100に制限し、レベル1は冗長性マッチングを4つの候補のみに制限し、圧縮率が15%悪いことを意味します。

図22.7. Gzipの圧縮レベル。

図は、各圧縮レベルをコンテンツタイプ別に分けたものです。ほぼすべてのケースで、JavaScriptがもっとも一般的なコンテンツタイプです。Brotliでは、もっとも高い圧縮レベルではJavaScriptの割合が低い圧縮レベルよりも高く、低い圧縮レベルではJSONが多くなっている。Gzipでは、JavaScriptのコンテンツタイプの分布はどのレベルでもほぼ同じです。

サイトの圧縮率を分析する方法

WebサイトのどのコンテンツがHTTP圧縮を使用しているかを確認するには、Firefox Developer Tools または Chrome DevTools を使用することが可能です。開発者ツールで、「ネットワーク」タブを開き、サイトを再読み込みしてください。HTML、CSS、JavaScript、フォント、画像などのレスポンスのリストが表示されるはずです。どれが圧縮されているかを確認するには、その応答ヘッダーのコンテンツエンコーディングをチェックします。列を有効にすることで、すべてのレスポンスについて一度に簡単に確認できます。これを行うには、列のタイトルを右クリックし、メニューの[レスポンスヘッダー]に移動して[コンテンツエンコード]を有効にします。

Gzipで圧縮された応答は “gzip “と表示され、Brotliで圧縮された応答は “br “と表示されます。この値が空白の場合、HTTP圧縮は行われません。画像の場合、これらのリソースはすでにそれ自体で圧縮されているため、これは正常です。

Chrome DevToolsでレスポンスのcontent-encodingをチェックする。
図22.8. Chrome DevToolsでレスポンスのcontent-encodingをチェックする。

サイトの圧縮を分析できる別のツールとして、GoogleのLighthouseというツールがあります。「テキストの圧縮を有効にする」監査を含む一連の監査を実行します。この監査では、リソースの圧縮を試み、少なくとも10%および1,400バイトが削減されたかどうかをチェックします。スコアに応じて、圧縮の推奨事項を結果に表示し、圧縮することでWebサイトに利益をもたらすリソースのリストを表示できます。

HTTP Archiveでは、すべてのモバイルページに対してLighthouse監査を実施しており、このデータから72%のWebサイトがこの監査に合格していることが確認されました。これは、昨年の 74%より2%少なく、これは昨年と比較して全体的にテキスト圧縮の使用率が高いにもかかわらず、わずかに低下しています。

図22.9. テキスト圧縮Lighthouseのスコア。

圧縮率を向上させる方法

コンテンツの圧縮方法を考える前に、そもそも送信するコンテンツを減らすことが、賢明である場合が多い。これを実現する1つの方法は、HTMLMinifierCSSNanoUglifyJS などのいわゆる「ミニマイズ」を使うことです。

送信するコンテンツの最小限の形式が決まったら、次は圧縮が有効であることを確認します。前のセクションで強調したように、有効になっていることを確認し、必要に応じてWebサーバーを設定します。

Gzip圧縮(DeflateまたはZlibとしても知られている)だけを使用している場合、Brotliのサポートを追加することは有益です。Gzipと比較して、Brotliは同じ速度でより小さなファイルに圧縮し、同じ速度で解凍する。

よく調整された圧縮レベルを選択できます。どの圧縮レベルが正しいかは、複数の要因に依存するかもしれませんが、より重く圧縮されたテキストファイルは、デコード時に多くのCPUを必要としないことに留意してください。したがって、圧縮前の資産の場合、圧縮レベルをできるだけ高く設定しても、ユーザーの観点からは欠点がありません。動的圧縮の場合は、圧縮にかかる時間と転送時間が短くなる可能性の両方を考慮して、より重く圧縮されたファイルをユーザーが、より長く待つ必要がないようにする必要があります。この違いは、両者の圧縮レベルの推奨値を見れば明らかです。

圧縮前のリソースにGzip圧縮を使用する場合、より小さなGzip互換ファイルを生成するZopfliの使用を検討してください。Zopfliは反復的なアプローチで非常にコンパクトな構文解析を見つけ、3-8%の高密度出力をもたらしますが、計算にはかなり時間がかかります。一方、Gzipはより単純ですが、あまり効果的ではないアプローチを採用しています。複数のコンプレッサーの比較 と、Gzipの異なる圧縮レベルを考慮した GzipとZopfliの比較 を参照してください。

Brotli Gzip
圧縮前 11 9 か Zopfli
動的に圧縮 5 6
図22.10. 使用する推奨圧縮レベル。

ウェブサーバソフトウェアのデフォルト設定を改善することは、ウェブパフォーマンスに時間を投資できない人々に大きな改善をもたらすでしょう。とくにGzip品質レベル1は異常値のようで、HTTPアーカイブ summary_response_bodies データで15%圧縮されるデフォルト6が有益でしょう。また、Brotliをサポートしているユーザーエージェントでは、Gzipの代わりにBrotliをデフォルトで有効にすることも大きなメリットになります。

結論

28,000件のHTTPレスポンスに使用された圧縮レベルを分析した結果、Gzip圧縮されたコンテンツの約0.5%にZopfliなどのより高度な圧縮器が使用されており、同様の「最適解析」アプローチはBrotli圧縮されたコンテンツの17%に使用されていることが明らかになりました。このことは、より効率的な方法が利用できれば、たとえ速度が遅くても、相当数のユーザーが静的コンテンツにこれらの方法を導入することを示しています。

HTTP圧縮の利用が増え続けており、とくにBrotliは前年の章と比較して大きく増加しています。いずれかのテキスト圧縮を使用したHTTPレスポンスの数は2%増加しましたが、Brotliは4%以上増加しました。増えたとはいえ、サーバーの圧縮設定をいじることで、より多くのHTTP圧縮を利用できる機会があることは確かです。ご自身のウェブサイトのレスポンスとサーバーの設定をよく見てみると、その恩恵にあずかれるでしょう。圧縮を使用していない場合は圧縮を有効にすることを検討し、圧縮を使用している場合は、その場で生成されるHTMLなどの動的コンテンツと静的コンテンツの両方で、圧縮レベルを高くするように圧縮方法を調整することを検討できます。一般的なHTTPサーバーのデフォルトの圧縮設定を変更すると、ユーザーに大きな影響を与える可能性があります。

著者

  • Lode Vandevenne
    Lode Vandevenneは、ソフトウェアエンジニアとしてGoogleスイスに勤務し、Zopfli、Brotli、JPEG XL画像フォーマットなどの圧縮プロジェクトに貢献しています。
  • Moritz Firsching
    Moritz Firschingは、Googleスイスのソフトウェアエンジニアで、プログレッシブ画像フォーマットとフォント圧縮を研究しています。それ以前は、数学者として多面体の研究をしていた。
  • Jyrki Alakuijala
    Jyrki Alakuijalaは、オープンソースソフトウェアコミュニティの活発なメンバーであり、データ圧縮の研究者でもあります。最近の研究テーマは、Zopfli、Butteraugli、Guetzli、Gipfeli、WebP lossless、Brotli、JPEG XL圧縮形式とアルゴリズム、および2つのハッシュアルゴリズム、CityHashとHighwayHashです。Google入社以前は、脳神経外科や放射線治療の治療計画のためのソフトウェアを開発していました。