
この記事では、弊社が実際に遭遇したWebサイト最適化における重大なトラブルとその解決策をナレッジとして記載します。
「良かれ」と思って導入した画像最適化プラグインが、予想に反してサイトパフォーマンスを大幅に悪化させてしまい、結果的にCDNの設定調整が必要となったというお話です。
- 関連サービス
- Web保守・運用サービス(ホスティング)
背景:一般的なSEO課題と画像最適化の必要性
Webサイト運営で最も重要な指標の一つがSEOです。
Webサイトは軽量でサクサクと表示されることが望ましく、特に画像等のリッチコンテンツを多く利用するサイトでは、画像ファイルの軽量化がSEO評価において非常に重要なポイントとなります。
従来のJPEGやPNG形式は圧縮比率によっては、データ容量が大きくなることがあります。 このような容量の大きい画像ファイルが多く設置されたサイトでは、データ通信容量の増大によりサイト表示が遅くなり、SEOの評価は低くなってしまいます。
次世代画像フォーマットという解決策
この課題を解決するのが、WebP(ウェッピー)やAVIF(エーブイアイエフ)といった次世代画像フォーマットです。 ブラウザにより表示可能なフォーマットは異なるものの、これらの形式では、画像品質を保持したままデータ容量を大幅に削減することが可能であり、次世代画像フォーマットを利用することで、SEO評価を向上させることができます。
しかしながら、既存コンテンツを1つ1つ次世代画像フォーマットへ置き換えるのは非常に手間がかかるうえ、Web制作運用業務において各ブラウザに対応する複数フォーマットを都度作成することは大きな作業負担となります。
WordPressのような人気のCMSでは、画像最適化のプラグインが多数開発されており、これらを用いることで、JPEGやPNG形式で構成されたサイトを、簡単に次世代フォーマットに対応させることが可能です。
ここだけ聞くと、「それだけでSEO評価があがるのであれば即導入!」と思われるかもしれませんが、そうは行かないのがWebシステムの難しさです。 安易な導入には大きな落とし穴が潜んでいます。
Webサイトの構成理解の重要性
ここで重要なのが、Webサイトシステム構成の理解です。 弊社で運用しているWebサイトは主に以下の要素から構成されています。
1. Webサーバー
2. DBサーバー
3. コンテンツ用ストレージ
4. CDN(コンテンツ配信ネットワーク)
5. バックアップサーバー
画像最適化プラグインは「1.Webサーバー」にインストールされ、「3.コンテンツ用ストレージ」に格納されているJPEGやPNGといった画像ファイルを次世代フォーマットへ変換、軽量化します。 そして「1.Webサーバー」から配信をする際に、画像最適化プラグインが動的にブラウザ毎で最適なフォーマットへ配信をしようとするアプローチを取ります。
画像最適化プラグインを利用することで、サイトを容易に次世代画像フォーマットに対応させることが可能となりますが、これらの動作や構成を理解せず導入した場合、重大なトラブルに発展することがあります。
プラグイン導入により、Webサイトの動作元となる「1.Webサーバー」の設定や挙動が変更される可能性は高く、動作や構成を把握している管理者が、事前の確認や検証の上で導入を進めることをおすすめいたします。
問題:CDNキャッシュヒット率が急落
ここからは弊社で実際に発生したトラブルのお話です。
とあるWebサイトにおいて、Web制作会社様が画像最適化プラグインを導入した結果、以下のような事象が発生しました。
- CDNキャッシュヒット率が90%から0.2%に急落
- オリジンサーバーへの負荷が急激に上昇
- サイトレスポンスの大幅な低下
- 全体的なユーザーエクスペリエンスの悪化
「良かれ」と思って導入したプラグインが、予想外の性能悪化を引き起こす結果となった内容です。
この際、弊社では画像最適化プラグインの導入情報は知らされておらず、発生している事象から調査を実施しました。 事象発覚から、弊社技術スタッフが実施した調査の流れや改善方法について書いていきたいと思います。
問題の発覚過程
定期監視での異常検知
とあるサイトの定期レポートを作成していた際に、キャッシュヒット率が著しく低下している事象を確認しました。 前回レポート内容と比較したところ、以下のような内容がわかりました。
- 弊社にて定期レポート作成の際、キャッシュヒット率の異常低下を確認
- 通常90%を維持していた平均キャッシュヒット率が0.2%という驚異的な低さに
- オリジンへのアクセスが60%以上増加
詳細調査の実施
弊社スタッフではWebサーバーの設定を変更していないことがわかっており、この事象についての調査を開始しました。 弊社技術スタッフがWebサイトに配置されているコンテンツのHTTPヘッダーを確認したところ、画像ファイルのみ通常とは異なる内容となっていることがわかりました。
- ステータスコード 304(Not Modified)が返されている
- Cache-Control CDNで指定している24hour(86400)ではなく、
private, max-age=0
に変化 - Content-Type JPGファイルへのアクセスであるが、
image/webp
としてレスポンス - Vary Varyヘッダに
Accept
が追加されていることを確認
アクセス解析も実施してみた結果、画像系ファイルのキャッシュヒット率はほぼ0%と著しく低下しています。

これらの結果から、オリジンとなるWebサーバーにおいて、何らかの動作が介入していることがわかりました。
弊社ではWebサーバーの設定を変更していないため、Web制作会社が設定可能な.htaccessファイルで何らかの設定が入っていることを予想し原因調査を進めました。
原因究明:WordPressのプラグインが影響している?
事象が出ているURLを基に、Webサーバーのディレクトリ階層を確認したところ、WordPressのとあるディレクトリに設置された.htaccessファイルに、原因となりそうな設定を見つけました。
※一部抜粋
<IfModule mod_headers.c>
<FilesMatch "(?i)\.(jpg|png|webp|jpeg)(\.(webp|avif))?$">
Header always set Cache-Control "private" # CDNキャッシュを無効化する設定
Header append Vary "Accept" # 当初想定していないヘッダータイプ
</FilesMatch>
</IfModule>
特定画像ファイル拡張子に対し、Cache-ControlヘッダーとVaryヘッダーを書き換えており、サイトから確認した際のHTTPヘッダー挙動と一致しています。
さらに全体的な設定内容をみていると、以下の挙動となっているようでした。
① Acceptヘッダーからアクセス元ブラウザがWebPに対応しているかチェックを実施
② WebPに対応していた場合は、ローカルで生成保持しているWebPファイルへサーバー内部転送処理し、元の画像ファイル(jpg、png)としてレスポンスを返す
③ Content-Typeヘッダーを image/webp
へ変更
④ 対象ファイルのCache-Controlヘッダーをprivate
、VaryヘッダーをAccept
へ変更
また、挿入されていた設定コメントを見る限り、WordPressのプラグインが自動で設定を書き換えているように見え、実際にWebP画像も生成されています。
どうやら、画像最適化のプラグインにより、ブラウザごとに最適な画像形式を配信するための設定が入っているようです。
弊社では、ここで初めて画像最適化プラグインが導入されたことがわかりました。
恐らくWordPressを管理しているWeb制作会社様が画像最適化プラグインを導入されたのではないかと思います。
2つの問題点:Cache-ControlとVaryヘッダーの指定内容
前述のとおり、この設定には2つの重大な問題があります。
1. Cache-Control: private
Header always set Cache-Control "private"
- プライベートキャッシュのみ許可(ブラウザキャッシュのみ)
- CDNでのキャッシュを無効化するようになっていた
2. Vary: Accept
Header append Vary "Accept"
- 利用しているAkamai CDNでは、“Accept-Encoding”以外は基本キャッシュしない仕様となっている
- サイトから確認した際、画像ファイルのみVaryヘッダーが”Accept”となっていた
1点目のCache-Controlヘッダーに関しては当時の設定的に影響はありませんでしたが、2点目のVaryヘッダーの内容が問題となっていそうです。
技術的な根本原因
これらの内容を見てみた結果、CDNキャッシュが上手く効かない問題の根本原因は、VaryヘッダーがAcceptに変更されている点にあることがわかりました。
見落とされがちな影響範囲
この問題は、以下の考慮不足から発生しました。
CDNとの設定連携不足
- 画像最適化プラグインがWebサーバーの設定ファイルを書き換えたことで、CDN設定とのミスマッチが発生
- CDN側ではデフォルトの動作としてVaryヘッダーに
Accept
が入っている場合、CDNキャッシュをしないルールとなっている
- CDN側ではデフォルトの動作としてVaryヘッダーに
プラグイン導入の影響範囲軽視
- Web制作会社様が「良かれと思って」対応されたものが裏目に
- 他案件では良い結果が出たとのことで、システム構成の違い(CDNの有無)を考慮せずに適用
- CMSのGUI操作の簡便なため、上述の設定ファイルへの変更が考慮されていなかった
- そのため、該当設定の際に連携や相談がなく発生してしまった形になります
解決策:CDN側での設定最適化
上述の事項を報告いたしましたところ、「プラグインの除去等の即時判断ができないが、サイトのレスポンスは改善したい」とご連絡をいただきましたので、CDN設定を熟知した弊社エンジニアが間に入り、プラグイン動作に考慮しつつ、対応を行いました。
Akamai CDNでの具体的な設定変更
- CDNサイドにてチューニングを実施
上述の通り、画像ファイルに限り、Webサーバーサイドからのレスポンスの際、VaryヘッダーがAccept
の値になっていたため、CDN側ではキャッシュをしない状態でした。 CDNキャッシュヒット率を上げるには、単純にVary: Accept
を許容すればよいのですが、.htaccessファイルから見える挙動を考えると、CDNキャッシュの観点から気になる挙動があります。
画像のURLは変えず、サーバー内部処理だけで動的に異なる画像ファイルフォーマットを返す
CDNのキャッシュは基本的にURLに紐づいたキャッシュをしますが、上記の条件では、URLは同一でも中身の異なる内容がWebサーバーからレスポンスされることが予想されます。
そのため、仮に初回アクセス時にWebP対応ブラウザからのアクセスにより、WebPファイルがCDNでキャッシュされた場合では、WebP非対応ブラウザでは以後サイト画像が見れない可能性が出てきてしまいます。
これらを許容可能な設定を検討した結果、CDNキャッシュを判断する際に利用するキャッシュキーを、レスポンス内容に合わせて変更する方法で設定を進めることにしました。
この方法であれば、ブラウザ毎で対応する画像フォーマットの画像データを、それぞれ別にCDNキャッシュすることができるので、Webサーバーの設定を変更することなく、CDNキャッシュを最適化できると考えました。
最適な設定プランの設計
今回のプラン設計では以下内容を考慮しました。
- サイトの不具合発生を最小化し、安全性を優先する
- 設定変更による無駄なリソース消費を防ぐ
- 発生中の不具合に対し、可能な限り最大のパフォーマンスが発揮できるようにする
設定方針
- Varyヘッダー値が
Accept
となっている場合でもCDNキャッシュを有効化- ただし、全体設定で有効化せず、WordPressパス以下の画像ファイルのみに限定する
- キャッシュ判別に利用するキャッシュキーを、Acceptヘッダーの値別に分けてCDNキャッシュさせる
- Acceptヘッダー値をキャッシュキーに挿入することで、確実にブラウザが対応する画像フォーマットのキャッシュデータを返す
- Edgeのcache-control設定は24時間キャッシュへ上書きする
Acceptヘッダーの値はブラウザやOS、バージョンで異なるため、上記のようにAcceptヘッダー値をそのままキャッシュキーとして利用した場合では、おそらくキャッシュヒット率は下がってしまいます。 しかしながら、今回はサイト稼働の不具合を最小化させたかったため、確実にCDNキャッシュからのアクセスを成功させる方法として、ブラウザが送信するAcceptヘッダー値を、加工せずそのまま利用する形としました。
運用後、一定期間様子を見たうえで、仮にキャッシュヒット率が低いままとなるようなら、キャッシュキーを以下のように調整する形を検討したいと思います。
- 現設定での例:
image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
- 調整想定の例:
image/webp,image/apng
上記設定を追加し、検証環境で動作のチェックを行いました。
検証環境による動作確認
設定を適用した結果、期待通りの挙動となりました。 結果は以下となります。
Chromeの動作
- Acceptが
image/avif,image/webp,image/apng,image/svg+xml,image/,/;q=0.8
に対し、Cache Keyに以下cid=~が挿入されていた
x-true-cache-key:/L/xxxxx.com/wordpress/wp-content/themes/wp-wa2023_09/img/logo.png vcd=6776 **cid=///PMUSER_ACCEPT=image%2favif,image%2fwebp,image%2fapng,image%2fsvg+xml,image%2f,%2f%3bq%3d0.8**
- 二度目のアクセスについては、x-chacheで対象CDNでキャッシュアクセスを示す
TCP_MEM_HIT from~
となっていた - content-typeは
image/webp
となっていた - cache-cotrolは24時間キャッシュを示すmax-age=86400が付与されていた
FireFoxの動作
- Acceptが
image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5
に対し、Cache Keyに以下cid=~が挿入されていた
x-true-cache-key:/L/xxxxx.com/wordpress/wp-content/themes/wp-wa2023_09/img/logo.png vcd=6776 **cid=///PMUSER_ACCEPT=image%2favif,image%2fwebp,image%2fpng,image%2fsvg+xml,image%2f*%3bq%3d0.8,*%2f*%3bq%3d0.5**
- 二度目のアクセスについては、x-chacheでAkamai CDNのキャッシュアクセスを示す
TCP_HIT from~
となっていた - content-typeは
image/webp
となっていた - cache-cotrolは24時間キャッシュを示すmax-age=86400が付与されていた
curlでacceptヘッダにimage/pngを指定してアクセス
curl -I https://xxxxx.com/wordpress/wp-content/themes/wp-wa2023_09/img/logo.png \
-H "Accept: image/png,image/*;q=0.8,*/*;q=0.5" \
-H "Pragma: akamai-x-cache-on, akamai-x-get-cache-key, akamai-x-check-cacheable, akamai-x-get-cache-tags, akamai-x-get-true-cache-key"
- Acceptで指定した
image/png,image/*;q=0.8,*/*;q=0.5"
が以下の通り、Cache Keyのcidパラメータとして挿入されていた
x-true-cache-key:/L/xxxxx.com/wordpress/wp-content/themes/wp-wa2023_09/img/logo.png vcd=6776 **cid=///PMUSER_ACCEPT=image%2fpng,image%2f*%3bq%3d0.8,*%2f*%3bq%3d0.5**
- 二度目のアクセスについては、x-chacheでAkamai CDNのキャッシュアクセスを示す
TCP_HIT from~
となっていた - content-typeは
image/png
となっていた - cache-cotrolは24時間キャッシュを示すmax-age=86400が付与されていた
正常動作と狙った動作が確認できましたので、先方へご連絡し、本番設定へ展開を実施しました。
劇的な改善結果
本番に適用後、グラフから確認した限りでは、事象が劇的に改善されたことが見て取れました。 以下は設定前後のグラフとなります。


上記対応の適用後、数時間で以下の改善を確認しました。
- 設定適用後、キャッシュヒット率を示すオフロード率が急激に上昇
- キャッシュヒット率が最大91%を超える水準まで回復
- サイトレスポンスが以前同様に高速化
- オリジンサーバー負荷が大幅に軽減
画像に対するCDNキャッシュが正しく反映されたことで、オフロード率が急上昇している様子が上図から確認できます。
その後、数日ほど様子を見ていたのですが、おおよそオフロード率平均で78%程度へ推移していました。 90%以上を目指したかったのですが、Acceptヘッダーを無加工で利用している影響も考慮すると、許容できる内容かと思います。
コンテンツ公開やキャッシュの効き方の影響もあるかと思いますので、もう数日待てばオフロード率は上昇していく可能性は大いに考えられます。
今回のCDN設定により、確実にオリジンとなるWebサーバーの負荷は下がっていると思いますので、もう少し様子を見たうえで、Acceptヘッダーを調整するかを改めて検討したいと考えています。


ここから学べること
よくある「部分最適化の罠」
この問題は、現代のWebサイト運営でよく発生する典型的なパターンでもあります。
「画像を軽くすれば速くなる」
↓
プラグイン導入
↓
CDN側の影響を考慮せず
↓
全体パフォーマンス悪化
現代的なWebサイト構成の複雑性
アプリケーションは以下のように複数の要素を経由して成り立っています。 故に一部分の変更でも、それが他の要素に影響を与えることがあります。
ブラウザ ↔ CDN ↔ WAF ↔ ロードバランサー(or DNSラウンドロビン) ↔ WordPress ↔ DB
そのため、プラグインを1つ追加するにしてもメリットだけでなくリスクに関しても考える必要があります。
事前検証の重要性
弊社案件以外でも、以下のような事例を耳にします。
- 品質劣化「変換をかけたら、WebPにはなったが元の品質から大きく劣化してしまった」
- データ消失リスク「既存物をそのまま変換したので元データがない」
- 既存コンテンツへの影響「設定していたスタイルが崩れてしまいページが表示できなくなった」
プラグインを無効化するだけでも解消する場合もありますが、元データがない場合、ストレージやシステムイメージの定期バックアップを取得していなければ復旧不可能となってしまいます。
推奨アプローチ:CDN側での画像最適化
既存のコンテンツが多量に存在する場合は、CMS側で対応するのではなく、CDNサイドで調整した方がよい結果を得られるケースが多いです。
CDNベンダーも本件のような課題は認識しており、対応するソリューションを提供しています。
Akamaiであれば、「Image & Video Manager」というサービス名で提供されており、画像に加えて、Gifや動画もCDNサイドで最適化したコンテンツの配信が可能です。
こちらのプロダクトは品質的にも、デザイン系のプロダクトにも導入されている実績があり、導入の効果測定も可能であり、弊社としてもおすすめしています。
余談:こぼれ話
プラグインコミュニティの投稿
今回対象としていたプラグインのコミュニティ投稿を確認すると、同様にCDNとの問題でサイトレスポンスが低下する事例がありました。
- ユーザー:Cloudflare無料版CDN利用者
- 状況:有料版プラグイン導入後、CloudflareがVary Headerの値を変更できないため機能せず
- 結果:CDNも有料版にアップグレードが必要という結論
このプラグインはサービスページに「CDN対応」と記載していましたが、どこのCDN、どのプランであるかは明示を避けていたため、上記のようなトラブルが発生していたと思われます。
最後に:全体を見据えたWeb運営の重要性
WordPress等のCMSは非常に便利であり、Web制作者にインフラストラクチャーの設定やチューニングを意識させないデザインになっています。
しかし、そのためにインフラへの意識が希薄になりがちという側面もあり、今回のようなケースが発生します。
現在のWebコンテンツではCDNは欠かせないものとなっており、それらとの兼ね合いも考慮する必要がある時代です。
SEOやサイト高速化を目的とした改善を行う際は以下が重要です。
- 現状の全体構成を把握
- 変更の影響範囲を事前評価
- 段階的な導入と継続監視
- 問題発生時の迅速な対応体制
CMS中心の思考から脱却し、CDN、サーバー、アプリケーション全体を俯瞰する視点が現代のWebサイト運営には不可欠です。
弊社のサポート体制
弊社では、こうした時代の変化に対応するため情報収集や検証を継続実施しています。 制作会社様から事前相談があった場合には以下のサービスを提供しています。
- 検証へのご助力
- 最適なサーバー/CDN設定のご提案
- 一括でのコンサルティング
知識が豊富な弊社エンジニアが、これらのサービスを提供していますので、類似の課題でお困りの方はぜひお問い合わせください。
この記事が同様の問題に直面している方の参考になれば幸いです。
