KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

KEIS BLOG

圧縮はどこで・何回やるか ― 事前圧縮が効く構成と、CDN に任せる構成

このシリーズは配信を軽くする話を続けてきました。前々回は ETag で再検証を安くCDN と ETag を入れたのにサーバ負荷が上がった ― 動的生成と CDN はなぜ相性が悪いのか)、前回は キャッシュバスティングで「変えた分だけ」失効更新したのに古い CSS が表示される ― キャッシュバスティングを content hash で正しくやる)。最後は 圧縮です。ただ正直に言うと、圧縮は前 2 回ほど「効く・効かない」がはっきりしません ―― 圧縮自体は安く、効き目は構成しだいだからです。その線引きを正直に見ていきます。

圧縮は安い ― でも 2 つの条件で話が変わる

まず誤解を解きます。gzip の圧縮はほぼタダです。典型的なページ(数十〜100KB のテキスト)なら 1 リクエストあたり 1ms 未満で、「gzip を有効にしたら CPU が跳ねる」は普通は起きません。では、わざわざ 事前に 圧縮して置いておく意味はどこにあるのか。話が変わるのは次の 2 つの条件です。

  • brotli を最高品質で効かせたいとき ―― brotli は品質を上げるほど縮みますが、最高品質はとても遅く、リクエストのたびにかけるのは現実的ではありません。事前なら「1 回だけ」なので、最高品質で時間をかけられます。
  • CDN を前に置かないとき ―― CDN があればエッジが圧縮を肩代わりしますが、無い構成では オリジンが全リクエストを捌きます。1 回 1ms でも、アクセスが増えれば積もる。事前圧縮なら、その都度の圧縮をまるごと無くせます。

逆に言えば、gzip だけ・かつ CDN 前段あり なら、事前圧縮の旨みはほとんどありません。効くのは「brotli を本気で使う」「CDN を挟まない」のどちらか(または両方)のときです。

だから「公開時に 1 回だけ・最高設定で」作り置く

静的配信なら、圧縮を 公開時の 1 回 に移せます。ページを生成するときに、圧縮済みファイル(.gz.br)も一緒に作って置いておく。配信時は その圧縮済みをそのまま返すだけ です。1 回しかやらないので、最高設定(gzip は最大レベル、brotli は最高品質。brotli はテキストで gzip より 15〜25% 小さい)で時間をかけられます。速度優先で品質を落とさざるを得ない動的圧縮とは対照的です。そもそも公開すると動くプログラムでなくファイルができる、という静的配信の仕組み自体は なぜ速くて、落ちなくて、狙われにくいのか ― ケイズのCMSの静的配信 で説明しています。

(事前圧縮ファイルが無くても問題ありません。その場合は配信側が動的圧縮にフォールバックするだけ ―― 事前圧縮は「あれば効く」上乗せです。)

図1: 動的圧縮はリクエスト毎にCPUを使う。静的なら公開時に1回最高設定で圧縮し配信は返すだけ
図1: 毎リクエスト圧縮(品質も妥協)に対し、事前圧縮は公開時に 1 回・最高設定でかけて配信は返すだけ

何を圧縮し、何をしないか

圧縮が効くのは テキスト系です。HTML・CSS・JavaScript・JSON・XML・SVG・テキストは繰り返しの多い構造なので大きく縮みます。一方、画像(PNG・JPEG・WebP)・PDF・動画はすでに圧縮済み。これらをもう一度圧縮しても、ほとんど縮まないうえに CPU だけ無駄に食います。だから事前圧縮の対象は テキスト系だけ に絞ります。

図2: テキスト系は圧縮で大きく減る。既圧縮の画像・PDF・動画は再圧縮しない
図2: テキスト系は圧縮で大きく減る。すでに圧縮済みの画像・PDF・動画は再圧縮しない(CPU の無駄)

大物の画像や PDF は、前回の「一意な URL + 長期キャッシュ」で軽くする側 ―― 圧縮ではなくキャッシュで効かせます。

効き目は構成しだい ― CDN なし/あり

事前圧縮が本当に効くかは、配信構成で分かれます。

  • CDN を前に置かない(静的サーバ直配信) ―― ここが事前圧縮の本領です。オリジンの静的サーバが、クライアントの対応に応じて 作り置きの圧縮ファイルをそのまま返します(その場で圧縮しない。gzip はそのまま、brotli 対応の配信なら最高品質の .br を)。全アクセスをオリジンが捌くからこそ、毎回の圧縮を消せる効果が大きい。Vary: Accept-Encoding で圧縮版・非圧縮版の取り違えを防ぎます。
  • CDN を前に置く ―― エッジが 初回に 1 回だけ圧縮してキャッシュします。以降はエッジが圧縮済みを返すので、オリジンの事前圧縮ファイルの出番は限定的。むしろ重複になるので、デプロイからは .gz/.br を除外します。

cms-core は どちらの構成も想定して、公開時に圧縮版を用意します。CDN を挟む運用ではエッジに任せ、挟まない運用では作り置きが効く ―― 同じ生成物が、構成に応じて使い分けられます。

図3: 静的サーバは作り置きの圧縮を返す+Vary、エッジは初回1回だけ圧縮してキャッシュ
図3: CDN なしなら静的サーバが作り置きの圧縮を返す(事前圧縮の本領)。CDN ありはエッジが圧縮するので出番は限定的

圧縮しても ETag は変わらない ― 転送と再検証は別の層

前回までと混ざらないように整理します。圧縮は「転送の形」を変えるだけで、コンテンツが変わったかどうか(ETag が見ているもの)とは別の話です。だから前々回の 安定した ETag と 304 はそのまま効き、前回の キャッシュバスティング も独立して働きます。Vary: Accept-Encoding は「同じ URL でも encoding が違えば別の表現」とキャッシュに教える仕上げです。3 つは互いに干渉せず、重ねて効かせられます。

ここで「圧縮した結果から ETag を計算するなら、結局リクエスト毎に圧縮することになるのでは?」と思うかもしれません。そうはなりません。前々回のとおり ETag は ファイルの更新時刻とサイズ から作られ、中身を圧縮してみる必要はありません。ETag は圧縮より前の段階で確定しており、変わっていなければ 304本体を送らない=そもそも圧縮も起きません。圧縮の CPU がかかるのは「実際に本体を送る(200)」ときだけで、事前圧縮はまさにそこを肩代わりします。
(逆に、もし ETag を 圧縮後データのハッシュ で作る設計だと、ETag を出すためだけに毎回圧縮が必要になり、304 で済むはずの場面でも CPU を食います ―― 更新時刻+サイズの ETag が効いてくる理由です。)

配信 3 部作のまとめ ― 重い仕事は「公開時に 1 回」

3 回かけて見てきた「配信を軽くする」3 つの層が出そろいました。

共通点は 「重い仕事を、利用者の来訪時ではなく公開時に 1 回だけ済ませる」 こと。前 2 つは効果がはっきりしていて、3 つ目は構成しだい ―― それでも「作っておけば、CDN 有りでも無しでも配信が軽い」という意味で、同じ設計思想の上にあります。ケイズの CMS は、公開(静的生成)のたびにこれらを自動で行います。

図4: 配信3部作ETag/content hash/事前圧縮、すべて公開時に1回で成立
図4: 配信 3 部作の役割分担。ETag=再検証を安く/content hash=変えた分だけ失効/事前圧縮=転送を軽く(構成しだい)。すべて「公開時に 1 回」
つまり
圧縮自体は安く(とくに gzip)、事前圧縮が効くのは「brotli を最高品質で使う」「CDN を挟まない」構成です。CDN を前に置くならエッジが圧縮するので出番は限定的。cms-core は両方を想定し、公開時に圧縮版を用意しておくので、構成が変わっても配信は軽いままです。

このブログは CDN(エッジ)配信なので、実際の圧縮はエッジが行っています。一方、CDN を挟まずに静的サーバだけで配る運用なら、同じ作り置きがそのまま効きます ―― 「公開時に 1 回」用意しておけば、構成が変わっても配信は軽いまま。それが、3 部作に共通する考え方です。配信が「なぜ速くて、落ちなくて、狙われにくいのか」の全体像は なぜ速くて、落ちなくて、狙われにくいのか ― ケイズのCMSの静的配信 にまとめています。

エンジニア募集中!

採用情報はこちら

CATEGORY

技術情報

思考

便利サービス

社内イベント

採用担当の戦い

その他

メンバー

LATEST ENTRY

2026.07.08

見慣れないIPアドレスの正体を調べる4つの方法

技術情報

2026.07.08

「providerを固定したのになぜ直らない?」Terraform初心者がハマる落とし穴

技術情報

2026.07.08

【KEISのメンバー #1】入社2年目・若手エンジニアに聞く、未経験からの1年と「続けられるエンジニア」

メンバー

2026.06.21

{% partial %} 文法リファレンス ― 名前・属性・型解決・スコープの全仕様

技術情報

2026.06.21

Liquid に自作タグを足す ― partial タグで見る作り方

技術情報

TAG