• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

株式会社ハイファイブクリエイト

  • SERVICE
  • ABOUT
  • WORKS
  • BLOG
  • NEWS
  • CONTACT
ホーム / ブログ / WordPress / 共用サーバーでOPcacheは効くのか?ベンチマークでは87.8%短縮、実サイトでは2.4倍遅くなった実測記録

共用サーバーでOPcacheは効くのか?ベンチマークでは87.8%短縮、実サイトでは2.4倍遅くなった実測記録

池田祐太郎 | 2026年9月4日 公開 コメントを書く

弊社が検証した iCLUSTA+ の1契約(PHP 8.4.20)では、OPcache のロード自体は利用者側の操作で成功しました。ところが速度はまったく改善せず、回避策として試した file_cache 方式では、WordPress のトップページ表示がかえって約2.4倍遅くなりました。

しかも、同じ設定を隔離したディレクトリでベンチマークすると 87.8%短縮と、かなり良い結果が出ていました。この数字だけを信じて本番に導入していたら、導入後の方がどうしようもなく遅くなるという結果になるところでした。

これはサーバーの不具合ではなく、PHP をどう実行するか(プロセスを永続させるかどうか)という実行方式の違いによるものです。また、確認したのは弊社が検証した1契約のみのため、同じサービスのすべての環境で同じ結果になるとは限りません。

共用サーバーで WordPress を運用していて、「とりあえず OPcache を有効にしてみよう」「OPcache 有効にしたら効果あるのでは」と考えている方に、導入前の参考として読んでいただければと思います。

なお、以前公開したWordPressが急に遅くなった!保守会社の自社サイトで起きた障害対応を包み隠さず公開しますでも、「OPcache を有効化したが、これ単体では改善しなかった」と書きました。今回は「なぜ効かないことがあるのか」を別のサーバーであらためて検証した内容になります。

目次

  • 1. 「遅いから OPcache」という定番の期待
  • 2. 前提確認: 「載っているか」ではなく「またいで効いているか」
  • 3. 実測1: ロードは通った。それでも hits は0のままだった
    • 3.1. extension_dir が "./" になっているときに本来のディレクトリを確認する方法
    • 3.2. ディレクトリに php.ini を置いてロードする
    • 3.3. 10回叩いても、1バイトも動かなかった
  • 4. 実測2: file_cache の罠 — ベンチマークで87.8%短縮、実サイトで2.4倍悪化
    • 4.1. 隔離ベンチマーク: 165.29ms → 20.21ms
    • 4.2. 実 WordPress: A/B/A で計測したら逆だった
    • 4.3. なぜ結果が逆になったのか
  • 5. 副産物: ディレクトリ php.ini は「マージ」ではなく「置き換え」
    • 5.1. 最小構成で置くと、書いていない設定が既定値に戻る
    • 5.2. 適用されるのは「実行されたスクリプトのあるディレクトリ」だけ
  • 6. まとめ: この環境では、PHP層のキャッシュより先に見るべきものがあった

「遅いから OPcache」という定番の期待

WordPress の管理画面で「ツール」→「サイトヘルス」と進むと、環境によっては次のような指摘が出ます。

オペコードキャッシュが有効化されていません

サイトヘルスに表示される「オペコードキャッシュが有効化されていません」の指摘。OPcache モジュールが読み込まれていない環境で出ます

OPcache は、PHP がソースコードを中間コード(オペコード)に変換した結果を保存し、次のリクエストでその変換を省く仕組みです。WordPress はコア・テーマ・プラグインで数千ファイル規模になるため、「有効にすれば速くなる」という期待は原理としては筋が通っています。

ただし前提があります。変換結果を置いた場所が、次のリクエストでも残っていることです。標準の OPcache は置き場所に共有メモリを使うため、PHP のプロセスがリクエストをまたいで生き続けている環境(php-fpm など)が前提になります。

共用サーバーでは、この前提が成り立たないことがあります。そして、成り立っていなくても OPcache は「有効」と表示されます。

前提確認: 「載っているか」ではなく「またいで効いているか」

そこで最初に見るべきなのは、OPcache が有効かどうかではなく、リクエストをまたいで効いているかどうかです。判定点はひとつ、hits が増えるかどうかです。

次のスクリプトを、確認したいサイトのドキュメントルートに置いてブラウザで開いてください。phpinfo() を丸ごと出すとサーバー内部のパスや環境変数まで表に出るため、判定に必要な項目だけを出しています。

<?php
// opcache-check.php — 確認が終わったら削除してください
header('Content-Type: text/plain; charset=UTF-8');
header('X-Robots-Tag: noindex, nofollow');

printf("PHP %s / SAPI %s\n", PHP_VERSION, PHP_SAPI);
printf("extension_loaded : %s\n", extension_loaded('Zend OPcache') ? 'true' : 'false');

$st = function_exists('opcache_get_status') ? @opcache_get_status(false) : false;
if ($st === false) {
    echo "opcache_get_status() が false。OPcache は無効です\n";
    exit;
}
printf("opcache_enabled    : %s\n", $st['opcache_enabled'] ? 'true' : 'false');
printf("num_cached_scripts : %d\n", $st['opcache_statistics']['num_cached_scripts']);
printf("hits               : %d\n", $st['opcache_statistics']['hits']);
printf("misses             : %d\n", $st['opcache_statistics']['misses']);
printf("used_memory        : %d\n", $st['memory_usage']['used_memory']);

見方はこうです。

  • opcache_enabled が false … そもそも OPcache が動いていません
  • true で、リロードするたびに hits が増える … 期待どおりに効いています
  • true なのに、10回リロードしても hits が 0 のまま … 今回の記事の状態です
プロセスが常駐する環境(ローカルの php-fpm)での出力。数回リロードすると hits が 4,840 から 17,977 に増え、num_cached_scripts はほぼ変わりません

3番目は注意が必要で、サイトヘルス上は「有効」と表示されるため、数字を見なければ対応済みだと思ってしまいます。

このファイルはサーバーの状態を外部に見せるものなので、確認後は削除してください。X-Robots-Tag は、消し忘れた場合に検索エンジンにインデックスされないようにするためのものです。

実測1: ロードは通った。それでも hits は0のままだった

検証したのは iCLUSTA+ の1契約、PHP 8.4.20 の環境です。

最初の確認で分かったのは、次の状態です。

  • SAPI の表記は cgi-fcgi
  • 拡張は42個が読み込まれていて、すべて静的に組み込まれている(extension= 行が有効になっているものは1つもない)
  • Zend 拡張はゼロ。つまり OPcache は読み込まれていない

では OPcache 自体が無いのかというと、そうではありません。ここで役に立つのがコンパイル時定数です。

extension_dir が "./" になっているときに本来のディレクトリを確認する方法

このサーバーでは ini_get('extension_dir') が "./" を返していました。マスターの php.ini が上書きしていて本来の拡張ディレクトリが見えない状態のため、この値を頼りに探しても見つかりません。

そこで、ini ではなく PHP のビルド時に埋め込まれた定数を見ます。

<?php
header('Content-Type: text/plain; charset=UTF-8');
printf("PHP_EXTENSION_DIR    : %s\n", PHP_EXTENSION_DIR);
printf("PHP_CONFIG_FILE_PATH : %s\n", PHP_CONFIG_FILE_PATH);
printf("ini の extension_dir : %s\n", ini_get('extension_dir'));
printf("opcache.so           : %s\n", file_exists(PHP_EXTENSION_DIR . '/opcache.so') ? '実在' : '無し');

PHP_EXTENSION_DIR は ini でどう上書きされていても変わりません。今回はこの定数から /usr/local/php84/lib/php/extensions という本来のディレクトリが分かり、そこに opcache.so(約1.2MB)があることを確認できました。

ディレクトリに php.ini を置いてロードする

iCLUSTA+ では、利用者がディレクトリごとに独自の php.ini を設置できます。公式サポート情報にも「はい、設置可能です。php.iniファイルの設定を有効にしたいディレクトリごとに設置してください」と明記されています(GMOクラウド サポート ch-580)。同じページの記述例には zend_extension 行の例も載っており、php.ini から Zend 拡張を読み込むこと自体は想定内の使い方です。

WordPress のファイルが無い隔離ディレクトリを作り、次の内容の php.ini を置きました。

; CGI版PHPの直接アクセス制限。既定値は 1 で、1 のままだと
; "Security Alert! The PHP CGI cannot be accessed directly" になります
cgi.force_redirect = 0

; マスターでは "./" に上書きされているため、ビルド時の本来値に戻します
extension_dir = /path/to/php/extensions

; 絶対パス指定にして、extension_dir の解釈に依存させません
zend_extension = /path/to/php/extensions/opcache.so

opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 128
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 1
opcache.revalidate_freq = 2

extension_loaded('Zend OPcache') も opcache_enabled も true になりました。ロードは成功です。

10回叩いても、1バイトも動かなかった

ところが、同じ URL に10回続けてアクセスすると、次の4項目が10回ともまったく同じ値でした。

項目1回目…10回目
num_cached_scripts1…1
hits0…0
misses1…1
used_memory9,181,072…9,181,072
同じスクリプトを10回開いても hits は 0 のまま。共有メモリがリクエスト間で引き継がれていない状態です

決定的なのは hits と misses です。共有メモリの中身が次のリクエストにも残っているなら、同じスクリプトを2回目に開いた時点で hits が増えるはずですが、10回開いても hits は0、misses は1のままだったため、毎回「初めて見るファイル」として扱われていることがわかります。

used_memory が1バイトも変わらないことも、これを裏付けています。毎回まっさらな共有メモリを確保してスクリプトを1本だけコンパイルし、レスポンスを返した直後に捨てているため、何度計測しても同じ値になります。

SAPI の表記は cgi-fcgi で、名前だけ見れば FastCGI でプロセスが常駐していそうに読めます。ですが実体は、リクエストごとに新しいプロセスが起動して終了する動きでした。SAPI 名はプロセスが永続する保証にはならないというのが、今回いちばん大きな気づきでした。

実測2: file_cache の罠 — ベンチマークで87.8%短縮、実サイトで2.4倍悪化

共有メモリが使えないなら、次の手は決まっています。OPcache には変換結果をディスクに保存する opcache.file_cache があり、opcache.file_cache_only = 1 を付ければ共有メモリを使わずファイルだけで動く、プロセスが永続しない環境のために用意された機能です。先ほどの php.ini に3行足しました。

opcache.file_cache = /path/to/opcache-cache
opcache.file_cache_only = 1
opcache.file_cache_consistency_checks = 1

隔離ベンチマーク: 165.29ms → 20.21ms

まず隔離ディレクトリで計測しました。約1.2MB・関数5,000個を定義するだけの巨大な PHP ファイルを機械生成し、require にかかる時間を計測しています。実行負荷はほぼゼロのため、計測値はほぼコンパイル時間そのものです。

条件中央値範囲
共有メモリのみ165.29ms140.97〜174.47ms
file_cache_only = 120.21ms16.43〜24.26ms

87.8%短縮。 正直、この時点では「効果あり」だと思っていました。

実 WordPress: A/B/A で計測したら逆だった

次に、同じ設定を WordPress に適用してトップページの表示時間を計測しました。時間帯による負荷変動に引きずられないよう、ON → OFF → ON と戻す A/B/A の順で計測しています。

状態最小中央値最大
ON(ウォームアップ済み・500ms間隔・8回)3,339ms3,901ms9,884ms
OFF(500ms間隔・8回)1,365ms2,026ms3,169ms
ON に戻す(間隔なし・6回)3,157ms8,002ms10,231ms
ベンチマークでは 87.8%短縮。同じ設定を実サイトに当てると 2.4倍遅くなりました

3行目だけリクエスト間隔を空けていないため、中央値と最大値は他の行と同条件では比較できません。負荷変動の影響を受けにくい最小値で比較すると、ON が 3,339ms と 3,157ms、OFF が 1,365ms で、約2.4倍の悪化であることがわかりました。OFF で下がり ON でまた上がったため、たまたま重い時間帯に当たったわけではないと思います。

ウォームアップ後のキャッシュは 1,777ファイル / 51.19MB。キャッシュ自体は正常に作られています。

なぜ結果が逆になったのか

原因はベンチマークの設計にありました。

file_cache_only はコンパイルを省く代わりに、キャッシュファイルの読み込みという別の作業を増やします。差し引きが得か損かは、1リクエストで何個のファイルを読むかで決まります。

  • ベンチマークで使った巨大ファイルは 1本。「1本の重いコンパイル」が「1本のファイル読み込み」に置き換わるだけの、これ以上ないほど有利な条件でした
  • WordPress は1リクエストで 数百の小さなファイルを読むため、file_cache_only ではその数百個ぶんの小さな .bin を毎回 open して read することになります
file_cache はコンパイルを「ファイルを読む」に置き換えます。読む回数がそのままコストになります

小さいファイルのコンパイルにかかる CPU 時間は、そもそも大きくありません。そこへ数百回のファイルオープンが乗ると、I/O がボトルネックになって逆転します。file_cache_consistency_checks = 1 のチェックサム検証と validate_timestamps = 1 の stat() も、ファイル数ぶんだけ上乗せされます。

教訓は、OPcache のベンチマークは対象アプリのファイル数分布を再現しないと、速くなるか遅くなるかすら誤る、ということでした。 87.8%という数字自体は正しく計測できています。計測方法が、答えたい問いに合っていなかっただけです。

副産物: ディレクトリ php.ini は「マージ」ではなく「置き換え」

最小構成で置くと、書いていない設定が既定値に戻る

ディレクトリに置く php.ini は、マスターの php.ini に追加されるのではなく、丸ごと置き換えます。公式サポート情報にも次のように書かれています。

お客さまのWebサーバー領域に独自のphp.iniを設置された場合、デフォルトのphp.iniの設定はすべて無視され、独自に設置されたphp.iniの設定に従ってPHPが動作します (GMOクラウド サポート ch-580)

最小構成の php.ini を置いたところ、次のようになりました。

設定項目マスターの値最小構成の php.ini を置いたとき
memory_limit512M128M(PHP の既定値)
session.save_pathサーバー指定の値空
mbstring.languageJapaneseneutral
読み込み中の拡張の数4242(欠落なし)

確認に使ったのは数行です。

<?php
header('Content-Type: text/plain; charset=UTF-8');
printf("memory_limit      : %s\n", ini_get('memory_limit'));
printf("mbstring.language : %s\n", ini_get('mbstring.language'));
printf("session.save_path : %s\n", ini_get('session.save_path') ?: '(empty)');
printf("拡張の数          : %d\n", count(get_loaded_extensions()));

拡張の数が変わらなかったのは、この環境では42個すべてが静的に組み込まれていたためです。extension= 行で読み込んでいる環境では、ここで拡張が読み込まれなくなります。

いちばん怖いのは session.save_path が空になることでした。これは公式サポート情報でも「初期値の /tmp という場所を指してしまい、iCLUSTAの複数あるWebサーバ間でセッションファイルが共有されずセッションがうまく機能しなくなります」と注意されています(ch-580)。PHP セッションを使うフォームなどが不安定になります。画面上は何事もなく動いて、特定の操作のときだけ失敗する壊れ方なので、置いた直後には気づきにくいものです。

対策は単純で、マスターの php.ini を全文コピーし、末尾に必要な行を追記した形で置くことです。php.ini は後に書いた行が勝つため、末尾への追記が上書きになり、ロールバックも置いた php.ini を削除するだけで済みます。

なお .user.ini は php.ini と併用でき、upload_max_filesize と max_execution_time の指定も維持されました。.user.ini は部分的な上書きとして読まれ、設置したディレクトリの下位にも適用されるため、変更したい項目がその範囲に収まるなら、そちらのほうが安全だと思います。

適用されるのは「実行されたスクリプトのあるディレクトリ」だけ

もうひとつ、置き場所です。CGI として動く PHP は、php.ini を実行されたスクリプトと同じディレクトリでしか探しません。親ディレクトリを遡ることはなく、今回の検証でも同様でした。なお、同じ系統のパネルを使っている お名前.com の共用サーバーGS では、ヘルプに「※設置したディレクトリのみ有効になります」と明記されています(お名前.com ヘルプ 9640)。同系統のサービスでは同様の挙動になる可能性があります。

ここで引っかかったのが、WordPress を /wp/ のようなサブディレクトリに置いている構成です。この構成ではドキュメントルート直下に「wp/wp-blog-header.php を読み込むだけの index.php」を置くのが定番ですが、そうすると実行されるスクリプトはドキュメントルートの index.php であり、WordPress 本体があるディレクトリではありません。

つまり、/wp/php.ini を置いてもフロントの表示には適用されず、適用されるのはドキュメントルート直下の php.ini です。弊社も最初はここを取り違えて、しばらく「設定したのに何も変わらない」と悩みました。確認用スクリプトをフロントと同じディレクトリに置いて php_ini_loaded_file() を出せば、どの ini が読まれているか分かります。

なお、ディレクトリの php.ini を読むのは CGI として実行されたときだけのため、CLI で動くサーバー cron には影響しませんでした。裏を返せば cron 側には設定が適用されないということでもあります。

適用されるのは、フロントで実行される index.php と同じディレクトリの php.ini だけです

まとめ: この環境では、PHP層のキャッシュより先に見るべきものがあった

今回分かったことを整理します。

  • OPcache のロードは利用者側でできた。しかし共有メモリはリクエストごとに捨てられ、hits は0のままだった。判定材料は SAPI 名ではなく、hits と used_memory の推移
  • file_cache_only は、WordPress では逆効果だった。隔離ベンチマークの87.8%短縮に対し、実サイトでは最小値比で約2.4倍の悪化。原因は数百の小ファイルを毎回開く I/O
  • ディレクトリ php.ini はマスターを置き換える。全文コピー+末尾追記でなければ、書いていない設定が既定値に戻る
  • php.ini が適用されるのは実行されたスクリプトのあるディレクトリだけ。サブディレクトリ設置の WordPress では、置き場所はドキュメントルート直下

この契約に対する弊社の判断は「OPcache は提案しない」でした。プロセスが永続しない以上、PHP 層でオペコードをキャッシュしても得られるものが小さいためです。この環境で速度を改善するなら、レンダリング結果を返すサーバー機能のページキャッシュや、生成済み HTML を配信する仕組みのほうが見込みがあると思います。ホスティング側に相談する場合も、論点は「OPcache の有効化」ではなく「PHP の実行方式」になります。

検証の進め方についても2つ。ひとつは 導入する前に計測すること。ベンチマークだけを見ていれば「87.8%短縮」という報告書が書けてしまうため、数字が正しくても問いに合っていないことがあります。

もうひとつは、テスト環境で行い、原状復帰まで含めて計画すること。今回は環境調査から計測まで合計で約2時間45分、うち40分がベンチマーク設計と php.ini の置き場所の取り違えによる手戻りでした。本番には触らず、確認用スクリプトも php.ini も検証後にすべて削除しています。キャッシュ置き場をドキュメントルート内に作らざるを得なかった場面では、コンパイル済みの PHP コードが Web から読めないよう .htaccess で読み取りを拒否し、外部から実際に 403 が返ることを確認してから進めました。

「有効になっているのに効いていない」は、数字を見なければ気づけません。サイトヘルスの表示だけで判断せず、hits が増えるかを10回確認してみてください。

共用サーバーの WordPress で表示速度にお困りの方は、弊社の WordPress 保守管理サポートからお気軽にご相談ください。今回のような導入前の計測から対応しています。

WordPress保守管理サービス

カテゴリWordPress 関連タグ:Webサイト高速化

池田祐太郎

IT担当を置けない中小企業の「外部IT部門」として、業務システムの設計・開発・運用を一貫して手掛けています。2016年から業務システム設計・運用を開始し、長期で仕組みを育て続ける進め方を強みとしています。2012年創業。WordPressの保守も10年以上継続しています。 プロフィール詳細

Reader Interactions

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

この記事と関連する記事

WordPressが急に遅くなった!保守会社の自社サイトで起きた障害対応を包み隠さず公開します
2026年8月7日
タグ: Webサイト高速化, 保守管理
カテゴリー: WordPress
遅延読み込み開始させる画像を変更させるWordPressカスタマイズ
2024年7月16日
タグ: Webサイト高速化
カテゴリー: TIPS
WordPressで特定の画像やアイキャッチ画像をlink rel=”preload”に設定する
2024年7月9日
タグ: Webサイト高速化
カテゴリー: TIPS

最初のサイドバー

外部IT部門

Search

最近の投稿

  • 自社ドメインのなりすましメールが対策済みかログインなしで調べる方法
  • wp-config.phpの中身が消えた原因はセキュリティプラグインだった
  • 共用サーバーでOPcacheは効くのか?ベンチマークでは87.8%短縮、実サイトでは2.4倍遅くなった実測記録
  • WordPressが急に遅くなった!保守会社の自社サイトで起きた障害対応を包み隠さず公開します
  • IT外注の費用はどう決まる?金額を比べる前に「範囲」を揃えるべき理由

カテゴリー

  • CSS初心者
  • HTML初心者
  • TIPS
  • WooCommerce
  • WordPress
  • エステサロン
  • お知らせ
  • キュレーション
  • サイトマップ
  • システム会社
  • デベロッパーツール入門
  • ブログ
  • ホームページ制作
  • ホームページ制作無料講座
  • メール
  • モバイル
  • 仕事のこと
  • 制作実績
  • 外部IT部門
  • 整体院
  • 美容院
  • 雑感

タグ

ai Android ChatGPT CMS css DALL-E elementor gmail google workspace Gutenberg HTML iPhone jQuery Mac Photoshop php SEO SNS ssh SSL Webサイト高速化 Windows WordPress WordPressカスタマイズ WordPressテーマ WordPress構築調査 WPRocket アクセス解析 クラウドソーシング サイト引っ越し サブスクリプション サーバー ショートカットキー スマホサイト スマートフォン セキュリティ ツール ブログ プラグイン マーケティング リニューアル レスポンシブWebデザイン 保守管理 最適化 集客するサイト構築

アーカイブ

CONTACT

お問い合わせはこちら

Footer

  • PRIVACY POLICY
  • 情報セキュリティ基本方針
  • 特定商取引法に基づく表示
  • 転載/引用

© 2026 high five create All rights reserved.