マルウェアを疑ったけど違った:WordPressの重さを生んだ“隠れリクエスト”の原因特定手順

記事
IT・テクノロジー

はじめに:症状は「重い」と「アクセスが増えたように見える」

あるWordPressサイトが、ある時期から急に重くなりました。体感だけでなく、計測でもページ表示に数秒〜十数秒かかることが増え、同時にアクセス解析(あるいは負荷ランキング)の数字が「不自然に増える」ように見えるようになりました。

具体的には、スマホで同じページを**1回更新しただけなのに、ヒット数が+1ではなく+13〜+14**のように増えてしまう現象が起きました。  
最初は「ボット?」「マルウェア?」「不正アクセス?」と疑いましたが、結論はまったく違うところにありました。

---

まずやったこと:1回の更新で“何本リクエストが発生しているか”を見える化する

WordPressが重いとき、原因の切り分けでまず重要なのはこれです。

> **「ブラウザが1回のページ表示で、実際に何本HTTPリクエストを追加で出しているか」**

管理画面側に、簡易的な「リクエスト負荷ランキング/トレース」的な仕組み(記録テーブル+表示画面)を用意して、以下の手順で確認しました。

1. 記録ログを全削除  
2. スマホで対象ページを**1回だけ**更新  
3. 記録されたリクエスト一覧を、**Referer(参照元URL)**で絞り込み  
4. `/wp-json/...` や `/admin-ajax.php` が何本出ているかを数える

この時点で、“1回更新で+13〜+14” という体感の正体が見え始めました。

---

判明したこと:ページ表示の裏で REST API が十数回呼ばれていた

ログを見て分かったのは、単にページHTMLを1回取りに行っているだけではなく、ページ表示の直後に **WordPress REST API が連続で呼ばれている**ことでした。

代表的には次のようなものです:

- `GET /wp-json/wp/v2/posts/{ID}?_fields=date` が短時間に大量発生  
- 参照元(Referer)がトップページ `/` になっているものが多い  
- さらに別のREST(例:PV送信のようなもの)も1本混ざる

ここで重要なのは、

> **アクセスが13倍に増えたのではなく、1回のページ表示の中で“裏リクエスト”が十数本追加で出ていた**

という点です。  
アクセス解析や負荷ランキングは「PHPに届いたリクエスト数」をカウントすることが多いので、裏でRESTが大量に走ると、見かけのヒット数も増えたように見えます。

---

次の切り分け:どのページがトリガーになっているか

「裏でRESTが走っている」ことが分かったら、次にやるのは **トリガーの特定**です。

今回のログでは、REST連打の参照元(Referer)が **記事ページではなくトップページ `/`** になっていました。  
つまり、

- 「記事ページを開いたときに走っている」のではなく  
- **トップページの表示に連動して走っている**

ということが分かります。

この段階で、原因候補はかなり絞れます。  
よくあるのは、トップページ内の「記事一覧」「人気記事」「ランキング」「スライダー」などのウィジェットが、表示後に追加処理をしているパターンです。

---

決定打:ページソース検索で “dateだけ取りに行くfetch” を発見

最後はフロント側(HTML/JS)を確認しました。

トップページのページソースを開いて、次の文字列を検索します。

- `_fields=date`
- `wp-json/wp/v2/posts`
- `fetch(`

すると、**記事IDごとに投稿日(date)を取りに行く処理**が見つかりました。  
しかも1箇所ではなく、複数のブロック(例:通常一覧、人気記事、スライダー)で似た処理が存在しており、状況によっては同じ記事IDに対して重複して呼ばれる可能性もありました。

この時点で結論は明確です。

> ページが重かった原因は、特定のフロントJSが「記事ごとに REST API を呼ぶ」設計になっていたこと

---

なぜ重くなるのか:1記事=1リクエスト の積み上げ

例えばトップページに13件のカードがあって、各カードの「投稿日を確認するため」にRESTを1回叩く実装だと、ページ表示だけで

- HTML本体:1回
- REST:13回(+場合によっては追加)
- 合計:十数回

になります。

これがキャッシュされず、しかも1本あたりの処理が重いと、体感が一気に悪化します。  
さらに「PHPに届くリクエスト数」も増えるため、ログや解析が“水増しされたように”見える現象も起きます。

---

解決:REST連打をやめる(またはバッチ化する)

解決の方針はシンプルです。

1) `<time datetime>` があるなら、それを使って判定(通信ゼロ)
記事一覧に日付情報がHTMLとして出ているなら、JSはそれを読んで “NEW” を判定すれば十分です。

2) `<time>` が無い場合でも「記事ごとにREST」はしない
どうしても日付がHTMLに無いウィジェットがある場合は、

- **必要な記事IDを集めて**
- **1回のバッチ問い合わせでまとめて判定結果を返す**

方式にするのが効果的です。  
(例:AJAXでまとめて問い合わせる、あるいは `include=...&_fields=id,date` のようなまとめ取得)_

サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す ココナラコンテンツマーケット ノウハウ記事・テンプレート・デザイン素材はこちら