テキスト圧縮

テキストデータのサイズを削減する技術。gzip、Brotli、deflate などのアルゴリズムが使われる。

テキスト圧縮とは、テキストデータの冗長性を利用してデータサイズを削減する技術です。Web では HTTP レスポンスの圧縮に gzip、Brotli、deflate などのアルゴリズムが広く使われており、ページの読み込み速度を大幅に改善します。テキストファイルは画像や動画と比べて冗長性が高いため、圧縮効果が特に顕著です。

テキスト圧縮の基本原理は、繰り返しパターンの検出と短い符号への置換です。たとえば「AAABBBCCC」という文字列は「3A3B3C」のように表現できます (ランレングス符号化)。実際の圧縮アルゴリズムはより高度で、LZ77 (スライディングウィンドウ方式) やハフマン符号化を組み合わせた deflate アルゴリズムが gzip の基盤となっています。HTML、CSS、JavaScript などのテキストファイルは繰り返しパターンが多いため、60〜80% のサイズ削減が期待できます。

gzip は最も普及した圧縮形式で、ほぼすべてのブラウザとサーバーがサポートしています。Brotli は Google が開発した圧縮形式で、Web フォント向けに 2013 年に公開され、HTTP 圧縮向けの版が 2015 年、仕様が 2016 年 7 月に RFC 7932 として公開されました。同じ内容なら gzip より一段小さくなりますが、差の大きさは内容と圧縮レベルによって変わり、HTML や JavaScript ではおおむね 1〜2 割です。最高レベルの圧縮は gzip の数倍の時間がかかるため、リクエストごとに圧縮する動的配信では低めのレベルが選ばれて差が縮み、あらかじめ圧縮して置ける静的ファイル (Static Compression) で最高レベルの差が出ます。Zstandard (zstd) は Facebook が開発した圧縮形式で、圧縮速度と圧縮率のバランスに優れています。HTTP の Content-Encoding: zstd には 2024 年に Chrome 123 と Firefox 126 が対応しました。

Web サーバーでの圧縮設定は、Nginx では gzip on;、Apache では mod_deflate で有効化できます。Nginx で Brotli を使う場合、brotli on; は本体に含まれるディレクティブではないため、別途 ngx_brotli モジュールを組み込む必要があります。設定を書いたのに圧縮されないときは、モジュールが組み込まれているか、圧縮対象の MIME タイプ (gzip_types など) に対象のファイル種別が含まれているかを先に確認します。CDN (CloudFront、Cloudflare など) も自動圧縮機能を提供しており、オリジンサーバーの設定なしで圧縮配信が可能です。ブラウザは Accept-Encoding ヘッダーで対応する圧縮形式を通知し、サーバーは Content-Encoding ヘッダーで使用した圧縮形式を返します。

よくある誤解として、すべてのファイルを圧縮すべきという考えがあります。JPEG、PNG、MP4 などのバイナリファイルはすでに圧縮されているため、再圧縮してもサイズはほとんど変わらず、CPU リソースを無駄に消費します。圧縮対象は HTML、CSS、JavaScript、JSON、XML、SVG などのテキストベースのファイルに限定すべきです。また、圧縮後のほうが元より大きくなる場合もあります。gzip は形式上のヘッダーとフッターだけで 18 バイトを使うため、1 バイトのデータを圧縮すると 21 バイトになります (ファイル名などのメタデータが付くとさらに増えます)。ただし効くかどうかを決めるのは大きさそのものではなく繰り返しの多さで、同じ並びが多い 300 バイトのテキストは 26 バイトまで縮む一方、同じ並びが現れない 200 バイトのデータは 223 バイトに増えます。数百バイトの API レスポンスに圧縮を入れるかどうかは、代表的な実データで圧縮前後のバイト数を測ってから決めます。

文字数カウントの観点では、圧縮後のデータはバイナリ形式であり文字数の概念が適用されません。圧縮前の文字数と圧縮後のバイト数は異なる指標です。ただし、テキストの文字数が多いほど圧縮の効果も大きくなる傾向があります。同じ単語やフレーズが繰り返し出現するテキストは圧縮率が高く、ランダムな文字列は圧縮率が低くなります。

この記事を共有