※当記事は、投稿者の技術的なメモを目的とした記事です。内容について参考にされる方は、ご自身の責任で十分に調査・検討の上でご利用ください。
- 静的ファイルとの比較テスト: サーバー上にシンプルなHTMLファイルを置いてTTFBを計測し、WordPressページと比較します。静的ページのTTFBが問題ない場合、WordPress側の処理(PHP/プラグイン等)に原因がある可能性が高い。
- テーマの切り分け: 現行テーマからデフォルトの軽量なテーマ(例: Twenty Twenty系)に一時変更してTTFBを再計測します。デフォルトテーマで明らかに高速化するなら、元のテーマに問題があると判断できます。テーマが原因の場合は最新バージョンへの更新や開発元への問い合わせを検討します。
- プラグインの切り分け: 全てのプラグインを停止し、TTFBが改善するか確認します。改善した場合はプラグインのいずれかが原因なので、一つずつ有効化して問題のプラグインを特定します。全停止でも改善しない場合、プラグインやテーマ以外(WordPress本体やデータベース)の要因を疑います。
- プロファイリングツールの活用: WordPressの実行に時間がかかる箇所を特定するために、開発者向けのプロファイラやデバッグプラグインを使います。例えば「Query Monitor」のような診断プラグインを使うと、どのプラグインやテーマ、設定が処理時間やクエリを多く消費しているか可視化できます。より高度な手法としてサーバーレベルでAPMツールを導入し、コード単位でボトルネックを分析することもできます。
WordPress本体やPHPバージョンによる影響
- WordPress本体のアップデート: WordPressは最新版へアップデートすることで内部の最適化が反映され、TTFB改善につながる場合があります。新しいバージョンではデータベースクエリの効率化や不要な処理の解消などパフォーマンス向上が含まれることが多いためです。実際、各リリースでクエリ処理の改善やバグ修正が行われており、アップデートするだけでレスポンスが向上するケースもあります。
- PHPバージョンのアップグレード: PHP自体のバージョンもサイトのTTFBに大きく影響します。一般にPHP 7以降(できれば8系)はPHP 5系より高速で、同じ時間で処理できるリクエストが格段に増えるためサーバー応答が速くなります。PHP7+は5.6に比べ約50%多くのリクエスト/秒を裁けると報告されています。PHPを最新安定版に上げることはセキュリティ強化だけでなくメモリ使用量削減や処理効率化による速度向上効果があり、結果としてTTFB短縮につながります。
- 互換性の確認: WordPress本体やPHPを更新する際は、使用中のテーマ・プラグインとの互換性にも注意します。互換性不良があると逆にエラーや遅延を招くため、ステージング環境でテストしてから本番適用すると安全です。アップデート後は再度パフォーマンス計測を行い、改善効果を確認します。
プラグインが原因の場合の特定方法
- 問題のプラグインを絞り込む: 前述のように全プラグイン無効化でTTFBが改善した場合、プラグイン由来の遅延です。プラグインを1つずつ有効化していき、TTFBが悪化するタイミングで有効にしたプラグインが原因と特定できます。手間はかかりますが確実な方法です。
- 代替のトラブルシューティングモード: プラグイン「Health Check & Troubleshooting」等の機能を使うと、サイト全体に影響を与えず一時的にプラグイン無効化状態で管理者のみ検証できます(特定プラグインの問題検出に便利です)。原因特定後は問題のプラグインの設定見直しや開発元への報告、代替プラグインへの置き換えを検討します。
- プラグインのプロファイリング: Query Monitorなどのツールでは各プラグインが実行したSQLクエリの回数・時間や、フックに費やした時間を確認できます。これにより「特定のプラグインが異常に重いクエリを投げている」「外部API呼び出しに時間を要している」等の状況を発見できます。コードレベルで分析できる場合はXdebugプロファイラを用いて実行時間の長い関数やメソッドを洗い出し、該当プラグイン内のどの処理がボトルネックか突き止める方法もあります。
- プラグイン設定の確認: 重いプラグインが判明した場合でも、プラグイン自体を除去せず設定変更で改善できるケースもあります。例えば高負荷な機能(アクセス解析やバックアップスケジューラなど)をオフにしたり、実行頻度を下げることでTTFB改善が可能です。プラグインごとのドキュメントを参照し、不要な機能を無効化することも検討します。
データベースやクエリの最適化方法
- クエリ数や実行時間の削減: ページ生成時に実行されるデータベースクエリが多すぎたり遅かったりするとTTFBが悪化します。まずは不要なクエリがないかコードやプラグイン設定を見直します。加えて、
WP_DEBUG
とSAVEQUERIES
を有効にしてデバッグログにクエリ一覧と実行時間を記録したり、MySQLのスロークエリログを分析して時間のかかっているクエリを特定します。特定したクエリに対して適切なインデックスを追加したり、クエリ自体を書き換えて高速化を図ります。インデックスが無い状態で大きなテーブルにクエリを投げると全件走査が発生し著しく遅くなるため、必要に応じてインデックス追加を検討します。 - オートロードデータの見直し:
wp_options
テーブルのautoload(自動読込)フラグがyes
のデータはページ読み込み毎に全て読み込まれます。この総量が大きいと初期応答が遅くなるため、autoloadデータ量をチェックします。一般的にautoload総サイズは800KB未満が望ましいとされています。以下のSQL例で総量や大きな項目を調べ、不要もしくは巨大すぎる項目はautoloadを無効化する(必要なときだけ読み込む)ことで負荷軽減できます。例えば一時的なキャッシュデータなどautoload不要なものはautoload
をno
に更新します。
-- 総オートロードデータサイズをバイトで計測
SELECT SUM(LENGTH(option_value)) AS total_autoload_bytes
FROM wp_options
WHERE autoload = 'yes';
-- 大きいオートロードデータ上位20件を確認
SELECT option_name, LENGTH(option_value) AS size_bytes
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size_bytes DESC
LIMIT 20;
- データベースの肥大化解消: データベース内の不要データを掃除するとクエリ負荷が下がりTTFB改善につながります。例えば投稿リビジョンやスパムコメント、期限切れのオプション等が大量に残っていると応答が遅くなる一因です。定期的なメンテナンスとして以下のような不要レコード削除やテーブル最適化を行います(実行前に必ずバックアップ取得)。
-- 古い投稿リビジョンを削除(※注意: 実行すると元に戻せません)
DELETE FROM wp_posts WHERE post_type = 'revision';
-- 使用されていないオーファンドpostmetaを削除(※注意)
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts wp ON wp.ID = pm.post_id
WHERE wp.ID IS NULL;
-- 期限切れの一時データ(transient)を削除(※注意)
DELETE FROM wp_options
WHERE option_name LIKE '%_transient_%';
上記のような直接DELETEを行う場合は、該当テーブルのデータを事前にSELECTで確認し、必要なものまで削除しないよう十分注意します。手動でのクエリ実行に不安がある場合、同様の処理を行うデータベース最適化プラグイン(例: WP-OptimizeやAdvanced DB Cleaner等)を利用する方法もあります。
- テーブルの最適化: MySQLの
OPTIMIZE TABLE
コマンドやphpMyAdminの「テーブルの最適化」機能でテーブルの断片化を解消し、無駄な領域を削減します。断片化を解消することでストレージI/O効率が上がり、結果としてクエリ応答が改善されます。特に大量の削除・更新が行われるテーブル(例:wp_options
やwp_postmeta
)は定期的な最適化を検討します。ただしInnoDBではOPTIMIZE TABLE実行時にテーブル再作成処理が走るため、一時的なロックやサイズ増加に注意が必要です(完了後に元に戻ります)。
一般的なレンタルサーバー環境における対策
- ページキャッシュの活用: レンタルサーバーなどCPU性能に限りがある環境では、プラグインやサーバー側機能によるページキャッシュを有効にすることが効果的です。キャッシュにより一度生成したページのHTMLを静的ファイルとして保存し、次回以降のリクエストではPHPやデータベースを介さずそのまま返せます。これによりサーバー処理時間が大幅に削減され、TTFBを劇的に短縮できます。多くのレンタルサーバーはサーバー側で簡易キャッシュを提供したり、WP Super Cache等のプラグイン利用が可能です。
- オブジェクトキャッシュの導入: 環境が対応していれば、MemcachedやRedisによるオブジェクトキャッシュを使うとさらに効果があります。データベースクエリの結果などをメモリ上にキャッシュして再利用することで、同じクエリを繰り返し実行する負荷を減らしTTFB改善につながります。レンタルサーバーでも「Redisオプション」などが用意されていればぜひ有効化を検討してください。
- プラグインや外部スクリプトの精査: 不要なプラグインやスクリプトは無効化・削除し、リクエスト毎の処理を軽量化します。プラグインが多すぎるとそれだけデータベースクエリや処理が増え、ページ生成が遅くなります。機能が被っているプラグインは一本化し、あまり使われていない機能は思い切って停止することも検討します。特に管理画面でのみ必要なプラグインはフロントエンドへの影響を最小化する設定がないか確認します。
- WordPressコアのタスク調整: レンタルサーバーではWP Cron(疑似cron)による定期処理がアクセスと同時に走る設定のままだと、アクセスのたびにバックエンド処理が発生してTTFBに影響する場合があります。
wp-config.php
にてDISABLE_WP_CRON
をtrueに設定し、サーバーのcronから適切にwp-cron.phpを実行するようにすると、アクセスごとの負荷を減らせます。併せて、プラグインが独自に定期ジョブを走らせていないかも確認し、必要以上に短い間隔のジョブは間隔延長または無効化を検討します。 - PHP・DB設定の見直し: レンタルサーバーの管理画面からPHP設定を変更できる場合、OPcache(PHPのオペコードキャッシュ)が有効になっているか確認します。OPcache有効時はPHPコードの解析をキャッシュできるため、WordPressの実行が高速化します。通常レンタルサーバーではデフォルト有効ですが、無効の場合は有効化を検討してください。また、PHPのメモリ上限や実行時間制限が極端に低いと処理途中で遅延や中断が発生する可能性があります。必要最低限256MB程度のPHPメモリを確保し(可能なら設定変更)、どうしても不足する場合はプラグイン削減や上位プラン検討も視野に入れます。
調査・改善のためのコード例メモ
※以下に挙げるコードはサイト高速化や原因調査に役立つ断片です。実行にあたっては自己責任で行い、特に削除系処理は事前バックアップを徹底してください。
- WordPressでのページ生成時間計測: サイトのPHP実行時間自体を把握するため、リクエスト開始から終了までの所要時間をログ出力するコード例です。
wp-config.php
にデバッグ設定を追記し、テーマのfunctions.php
(またはカスタムプラグイン)にフックを追加します。こうすることで各ページの生成時間や重いクエリをログファイルで確認できます。
// wp-config.php に追記(デバッグモードとクエリ記録を有効化)
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('SAVEQUERIES', true);
// functions.php 等に追記(シャットダウンフックで時間計測&ログ)
add_action('shutdown', function() {
global $wpdb;
// リクエスト開始から現在までの経過時間を計測
$elapsed = round(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], 4);
error_log("Page generated in {$elapsed} sec");
// 時間のかかったクエリがあればログ出力(0.1秒超を基準)
if (!empty($wpdb->queries)) {
foreach ($wpdb->queries as $query) {
list($sql, $duration, $caller) = $query;
if ($duration >= 0.1) {
error_log(sprintf('Slow query (%.3fs): %s', $duration, $sql));
}
}
}
});
上記を設置後、ページを閲覧するとwp-content/debug.log
に「Page generated in **秒」や遅延クエリ(Slow query)が記録されるようになります。これにより、どのページでサーバー処理に時間がかかっているか、またどのSQLクエリがボトルネックかを簡易的に把握できます。調査後は不要となるため、このコードはコメントアウトまたは削除してください。
- プラグイン別の読込時間計測: どのプラグインのロードに時間がかかっているか調べる簡易コードです。各プラグイン読み込み直後にタイムスタンプを取り、差分を出力します。このコードを
mu-plugins
(Must-Useプラグイン)として配置するか、またはplugins_loaded
フック内で実行することで、管理者画面上部などに結果を表示できます。
// mu-plugins/plugin-profiler.php
<?php
/**
* Plugin Load Profiler
*/
add_filter('plugin_loaded', function($plugin) {
static $lastTime = null;
$now = microtime(true);
if ($lastTime !== null) {
error_log(sprintf('Plugin %s loaded in %.4f sec', $plugin, $now - $lastTime));
}
$lastTime = microtime(true);
return $plugin;
});
このコードは各プラグインが読み込まれる度に、その直前からの経過時間を計測しログに出力します。ログを確認することで、特に読み込みに時間のかかったプラグインを発見できます。ただし上記は概算の簡易計測であり、より正確なプロファイリングには前
述のQuery Monitorなど専門ツールの使用をおすすめします。
- データベース関連の調査SQL: 前述のオートロードデータ確認クエリや、その他ボトルネック検証に役立つSQL例です(phpMyAdminやWP-CLIの
wp db query
コマンドで実行できます)。
-- Autoload合計サイズと上位オプション名の確認(上記参照)
-- テーブルの行数が多い順トップ5を調べる(大規模なテーブル特定)
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY table_rows DESC
LIMIT 5;
-- 特定のページ表示で実行されるクエリ一覧を見る(SAVEQUERIES有効時、ページ下部に出力)
-- functions.phpに以下を追加してページHTML内にクエリ一覧コメントを挿入
/*
add_action('wp_footer', function() {
global $wpdb;
echo "<!--\n";
foreach ($wpdb->queries as $q) {
echo $q[1] . "s | " . $q[0] . "\n";
}
echo "-->";
});
*/
なお、調査の結果データベースの問題が見つかった場合でも、安易に全削除や変更を行うのは避け、必ずバックアップを取ってから慎重に実施してください(特に上記のDELETE文を用いたクエリは要注意です)。必要に応じて専門家に相談することも検討しましょう。