ウェブ開発 最新ニュース UPDATES

AWS Graviton5搭載のEC2 R9gが一般提供開始。R8g比で最大25%の性能向上

AWS Graviton5搭載のEC2 R9gが一般提供開始。R8g比で最大25%の性能向上

AWSがGraviton5プロセッサを搭載したEC2 R9gとR9gdインスタンスを一般提供開始した。メモリ最適化インスタンスの新世代で、R8gと比較してコンピュート性能が最大25%向上している。

Graviton5はDDR5メモリの高速化、L3キャッシュの5倍拡大、ネットワーク帯域幅の最大2倍化など、複数のハードウェア改良を備える。データベースやインメモリキャッシュなどメモリ集約型のワークロードで効果が大きい。

この記事ではR9gの技術的な変更点、インスタンススペック、移行手順、利用可能リージョンを解説する。

Graviton5がもたらす性能向上の全容

Graviton5がもたらす性能向上の全容

Graviton5プロセッサはGraviton4から複数のハードウェア改良が加えられた。まずコンピュート性能がvCPUあたり最大25%向上している。これは命令処理の効率化と高クロック動作によるものだ。またAWSがこれまでに構築した中で最もエネルギー効率の高いプロセッサでもある。

従来のR8gインスタンス(Graviton4)
コンピュート性能 基準値
メモリ DDR5 5600 MT/s
L3キャッシュ 標準サイズ
ネットワーク帯域幅 最大50 Gbps
EBS帯域幅 最大36 Gbps
新しいR9gインスタンス(Graviton5)
コンピュート性能 最大25%向上
メモリ DDR5 8800 MT/s
L3キャッシュ 5倍拡大
ネットワーク帯域幅 最大100 Gbps
EBS帯域幅 最大72 Gbps
※48xlargeサイズでの比較。ネットワークとEBS帯域幅は最大値。

このデモはGraviton4(R8g)とGraviton5(R9g)の主要スペックを比較している。特にL3キャッシュの5倍拡大とメモリ帯域の高速化がデータ処理の遅延低減に効く。

メモリとキャッシュの大幅強化

メモリはDDR5 8800 MT/sに対応した。Graviton4の5600 MT/sから大幅に高速化されており、AWSのクラウド上で利用可能な最速のメモリ帯域を実現している。これは大量のデータを扱うインメモリキャッシュ・データベースにとって応答時間の短縮に直結する。

L3キャッシュも5倍に拡大された。L3キャッシュとはCPU内部にある高速なメモリ領域で、頻繁にアクセスするデータを一時的に保持する役割を持つ。この容量が増えると、主メモリへのアクセス回数が減り、データ処理の遅延が小さくなる。データ局所性が高いワークロードほど恩恵を受けやすい。

ネットワーク帯域幅とパケット処理の改善

ネットワーク帯域幅とAmazon EBSの帯域幅は、最大サイズのインスタンスで最大2倍に向上した。48xlargeではネットワークが最大100 Gbps、EBSが最大72 Gbpsに達する。またパケット処理性能は最大3倍に改善されている。

さらにR9gとR9gdはInstance Bandwidth Configuration(IBC)に対応している。これはEBSとネットワークの帯域配分を25%単位で調整できる機能だ。データベースやキャッシュなど、帯域要件が特定方向に偏るワークロードで性能を最適化できる。例えばネットワーク処理が少なくディスクI/Oが多いワークロードでは、帯域をEBS側に寄せるといった調整が可能になる。

Nitro Isolation Engineによるセキュリティ強化

Nitro Isolation Engineによるセキュリティ強化

すべてのR9gとR9gdインスタンスはAWS Nitro System上で動作する。Nitro Systemは仮想化、ストレージ、ネットワークを専用ハードウェアにオフロードする仕組みだ。これにより仮想マシンのオーバーヘッドが減り、ベアメタルに近い性能と強固なセキュリティ分離を両立できる。

R9gとR9gdにはNitro Isolation Engine(NIE)が搭載されている。NIEはC9gとM9gで今年前半に導入されたコンポーネントで、仮想マシン間の分離を強制する役割を担う。仮想マシンのメモリ、CPUレジスタ状態、I/Oデバイスへのすべてのアクセスを最小限のAPIセットで仲介する。

仮想マシンA 独立して動作
仮想マシンB 独立して動作
Nitro Isolation Engine メモリ・CPU・I/Oアクセスを仲介
Nitro System 専用ハードウェア 仮想化・ストレージ・ネットワークを処理
※NIEがすべてのアクセスを仲介することで、仮想マシン間の分離を保証する。

このデモはNIEが仮想マシンとハードウェアの間に位置し、すべてのアクセスを仲介する関係を示している。分離の保証はソフトウェア的な工夫ではなく、形式的な数学証明によって裏付けられている点が特徴だ。

NIEの特徴は形式検証(formal verification)という手法を活用している点にある。これはハードウェアやソフトウェアが意図通りに動作することを数学的に証明する手法だ。特定のテストケースだけでなく、あらゆる条件下で正しく動作することを保証する。この取り組みにより、Nitroはクラウドハイパーバイザーとして初めて形式検証を受けた存在になった。

形式検証の対象範囲や前提条件などの詳細はAWSのテクニカルホワイトペーパーで公開されている。セキュリティ要件が厳しい金融系ワークロードやマルチテナント環境を扱う場合には、このホワイトペーパーを参照してリスク評価に役立てるとよい。

R9gとR9gdのインスタンススペック

R9gとR9gdのインスタンススペック

R9gとR9gdはそれぞれ11サイズで提供される。最小のmediumから最大のmetal-48xlまで、幅広い要件に対応する。以下では2つの違いを中心に説明する。

R9gインスタンス
EBSストレージのみ使用
データベースやキャッシュに最適
最大192 vCPU / 1536 GiBメモリ
R9gdインスタンス
ローカルNVMe SSDを搭載
低レイテンシの一時ストレージが必要な用途に最適
最大192 vCPU / 1536 GiBメモリ / 11.4 TB NVMe
※どちらも同じコンピュート性能とネットワーク性能を持つ。ストレージ構成のみ異なる。

このデモはR9gとR9gdの違いを整理している。NVMe SSDの有無が唯一の差で、用途に応じて選べる。

R9gのスペック

R9gはEBSストレージのみを使用する構成だ。最小のr9g.mediumは1 vCPUと8 GiBメモリ、最大のr9g.48xlargeとr9g.metal-48xlは192 vCPUと1536 GiBメモリを搭載する。ネットワーク帯域幅はmediumから2xlargeまで最大15 Gbps、8xlargeで17 Gbps、12xlargeで25 Gbps、16xlargeで34 Gbps、24xlargeで50 Gbps、48xlargeで100 Gbpsに達する。

EBS帯域幅はmediumから4xlargeまで最大12 Gbps、8xlargeで12 Gbps、12xlargeで18 Gbps、16xlargeで24 Gbps、24xlargeで36 Gbps、48xlargeで72 Gbpsとなっている。データベース用途ではEBS帯域幅が性能のボトルネックになりやすいため、サイズ選定の際はこの値にも注目したい。

R9gdのNVMeストレージ

R9gdはR9gと同じコンピュート性能とネットワーク性能を持ちながら、ローカルNVMe SSDを搭載している。mediumでは59 GB、largeで118 GB、xlargeで237 GBとサイズに応じて容量が増える。最大のr9gd.48xlargeでは3台の3800 GB NVMe SSD(合計11.4 TB)を備える。

ローカルNVMe SSDはEBSと比べてレイテンシが低く、一時的なスクラッチ領域やキャッシュ用途に向いている。オープンソースデータベース、分散リアルタイムビッグデータ分析、大規模インメモリデータベース、大容量キャッシュワークロードで効果を発揮する。

R8gからの移行と始め方

R8gからの移行と始め方

R8gで運用中のワークロードがある場合、R9gへの移行はシンプルだ。多くのアプリケーションでコード変更は不要。同等サイズのR9gインスタンスを選択すれば、そのままより高い性能を得られる。

STEP 1 R8gインスタンスを運行中か確認
STEP 2 同等サイズのR9gインスタンスを選択
STEP 3 Arm64対応のAMIから起動
STEP 4 アプリケーションを実行して性能を確認
※多くのアプリケーションではコード変更不要。Arm64対応イメージを使えばそのまま動作する。

このデモはR8gからR9gへの移行手順を4ステップで示している。インスタンスタイプを変更するだけで性能が向上するケースが多い。

対応OSとコンテナ環境

R9gはAmazon Linux 2023、Amazon Linux 2、Ubuntu 22.04以降、RHEL 8.4以降、SUSE Linux Enterprise Server 15 SP3以降、Debian 12以降など主要なLinuxディストリビューションに対応する。EC2コンソールからArmベースのAMIを選択すれば、すぐに起動できる。

コンテナワークロードではAmazon EKS、Amazon ECS、標準的なKubernetes環境で動作する。Arm64向けにビルドされたマルチアーキテクチャのコンテナイメージなら変更なしで動く。Dockerイメージをマルチアーキテクチャ対応にしておくと、x86からArmへの移行がスムーズになる。

移行を支援するツール

AWSはGravitonへの移行を支援する複数のリソースを提供している。Graviton Getting Started Guideは構築、実行、最適化の方法をまとめたガイドだ。Graviton Savings Dashboardではコスト削減効果を追跡できる。AWS TransformはJavaアプリケーションをx86からGraviton向けに変換するコード変換を自動化するツールだ。

Javaアプリケーションの場合、依存ライブラリにネイティブコードが含まれているとArm64への移行が難しいことがある。AWS Transformはこうしたコード変換を自動化して移行の手間を減らす。まず小規模なワークロードで試し、問題がないことを確認してから本番移行に進むのが現実的な進め方だ。

料金と利用可能リージョン

料金と利用可能リージョン

R9gとR9gdは米国東部(バージニア北部、オハイオ)、米国西部(オレゴン)、欧州(フランクフルト)の各リージョンで利用できる。日本国内のリージョン(アジアパシフィック東京)では現時点で提供されておらず、今後の展開が待たれる。

購入オプションはSavings Plans、On-Demand、Spot Instances、Dedicated Instances、Dedicated Hostsから選択可能だ。長期運用する場合はSavings Plans、一時的なバッチ処理やテスト用途ではSpot Instancesがコスト効率に優れる。料金の詳細はAmazon EC2の料金ページで確認できる。

インスタンスサイズや購入オプションによって価格が異なるため、ワークロードに合わせて最適な組み合わせを選ぶことが重要だ。特にR8gと比較した場合、同じサイズでも性能が向上しているため、より小さなサイズに移行してコストを削減できる可能性もある。

この記事のポイント

  • AWS Graviton5搭載のEC2 R9gとR9gdが一般提供を開始した
  • R8g比でコンピュート性能が最大25%向上し、エネルギー効率も改善
  • DDR5 8800 MT/sメモリとL3キャッシュ5倍拡大でデータ処理が高速化
  • Nitro Isolation Engineにより形式検証されたセキュリティ分離を実現
  • R9gはEBSのみ、R9gdはローカルNVMe SSDを搭載した構成
  • R8gからの移行はコード変更不要のケースが多く、Arm64対応イメージでそのまま動作
WPLP Cookie Consent脆弱性を狙った攻撃からWordPressを守る3つの対策

WPLP Cookie Consent脆弱性を狙った攻撃からWordPressを守る3つの対策

Cookie同意プラグイン「WPLP Cookie Consent(スラッグ gdpr-cookie-consent)」のバージョン4.4.1以前には、未認証の攻撃者に任意のファイルをアップロードされる脆弱性がある。サイトを守るには、プラグインを4.4.2以上へ更新し、アップロードディレクトリ内でのPHP実行をサーバー側で拒否し、不正な管理者アカウントが作られていないか確認することが最優先だ。

なぜWPLP Cookie Consent 4.4.1が危険なのか

なぜWPLP Cookie Consent 4.4.1が危険なのか

この脆弱性は、プラグインのREST APIエンドポイントに認可の不備があることから発生する。攻撃者は誰でもアクセスできる2つのエンドポイントを悪用し、WordPressのオプション設定を書き換えたうえで、任意のファイルをサーバーに保存できる。特に問題なのが、保存先が通常のアップロードフォルダ(wp-content/uploads)であり、ファイル名や拡張子の検証がまったく行われていなかった点だ。

つまり攻撃者は「画像ファイルに見せかけたPHPプログラム」をサイトに置くだけで、その後の実行に成功すれば管理者権限を奪取できる。バージョン4.4.1は攻撃が確認された時点で最新版だったため、更新を怠っていたサイトだけでなく、常に最新にしていたサイトも危険にさらされた。修正版の4.4.2が公開されてからは、この経路は塞がれているが、攻撃キャンペーンがすでに自動化されて動いている以上、更新前のサイトは今も標的になる。

攻撃の流れと侵入の仕組み

攻撃の流れと侵入の仕組み

実際に確認された攻撃は、わずか20秒足らずで4段階のプロセスが自動実行される。最初にユーザー一覧を取得して管理者のユーザー名を特定し、次にプラグイン固有のオプションを毒して鍵をすり替え、最後にその鍵を使ってファイルを書き込む。下の図はその一連の流れを表している。

STEP 1 REST APIでユーザー一覧を取得される
STEP 2 store-authエンドポイントでオプションを改ざん
STEP 3 upload-logoエンドポイントでPHPファイルを書き込み
STEP 4 書き込んだPHPを実行しようとするがサーバー側のルールでブロック
攻撃者の操作  防御策が機能した部分

この攻撃チェーンのうち、最初の3段階は特定のプラグインがなければ成立しない。一方で、最後のPHP実行だけはサーバー側の設定次第でどのサイトでも防げる。ここが多層防御の要になる。

まず行う3つの緊急対応

まず行う3つの緊急対応

サイトがこの脆弱性の影響を受けるかどうかに関係なく、次の3つを優先して実行する。順番はプラグインの更新、サーバー設定の確認、不正アカウントの確認が推奨される。

プラグインを4.4.2以上へ更新する

WPLP Cookie Consent(gdpr-cookie-consent)を使っている場合、まず管理画面の「プラグイン」から更新が来ていないか確認する。更新が見つからない場合は、WordPress.orgのプラグインページから最新版を手動でダウンロードし、既存のプラグインを上書きする。バージョン4.4.2では、脆弱性の原因だったアップロード用エンドポイントが削除され、残ったREST APIにもHMAC-SHA256署名によるリクエスト検証が追加されている。

更新後は、キャッシュ系プラグインを使っている場合はキャッシュを削除しておく。古いRESTエンドポイントの応答がキャッシュに残っていると、攻撃者からまだ有効に見えることがあるためだ。

アップロードディレクトリ内でのPHP実行を拒否する

今回の攻撃では、脆弱なプラグインによって「wp-content/uploads」ディレクトリにPHPファイルが書き込まれた。しかし、そのディレクトリ内でのPHP実行がサーバー側で拒否されていたため、攻撃は最終段階で失敗している。この設定は多くのレンタルサーバーで最初から有効になっているが、そうでない環境もある。

Apacheサーバーの場合、wp-content/uploads ディレクトリに以下の内容の .htaccess ファイルを置くことで、PHPファイルの実行を拒否できる。

<FilesMatch "\.(php|php5|phtml)$">
  Require all denied
</FilesMatch>

Nginxの場合は、サーバー設定で該当ディレクトリに対するPHPの処理を除外する。レンタルサーバーを利用しているなら、管理パネルに「PHP実行の無効化」や「セキュリティ設定」が用意されているか確認する。設定を変更できない場合は、サーバー会社に問い合わせて、アップロードディレクトリ内のPHP実行がブロックされているか確認するのが確実だ。

修正前
wp-content/uploads 内で PHP ファイルが実行可能
→ アップロードされたPHPが実行され、サイトが乗っ取られる
修正後
wp-content/uploads 内で PHP ファイルの実行を拒否
→ アップロードされても実行されず、攻撃が失敗する
危険な状態  安全な状態

上の対比のように、ファイルが置かれても実行できなければウェブシェルとして機能しない。プラグインの更新とあわせて、このサーバー側の防御を必ず確認する。

不正な管理者アカウントを探す

今回確認されたマルウェアは、実行に成功すると管理者アカウントを自動生成する。しかも、登録日時を既存ユーザーの日時に合わせて改ざんするため、「新しく作られたユーザー」を探すだけでは見つからない。次の3つの兆候を手がかりに、phpMyAdminやWP-CLIで WordPress の wp_users テーブルを確認する。

  • ユーザー名が「サイトのドメイン名+ランダム3文字」になっている
  • 表示名が「Lucas Hayes」になっている
  • メールアドレスのドメインが ifuqpatr.com になっている

心当たりのない管理者アカウントを見つけたら、そのユーザーを削除し、全ユーザーのパスワードをリセットする。また、登録日時が既存ユーザーと完全に一致するアカウントがないかもあわせて確認する。

侵害を検知する具体的な手順

侵害を検知する具体的な手順

すでに攻撃を受けた形跡がないかは、ログとファイルの両面から確認する。攻撃が失敗していても、ファイルの残骸や不審なアクセスが残っていることが多い。

サーバーのアクセスログを精査する

攻撃者は決まったエンドポイントに順番にアクセスする。アクセスログで次のパターンを検索し、該当するリクエストが記録されていないか確認する。

  • GET /wp-json/wp/v2/users?per_page=100
  • POST /wp-json/wplp-react-gdpr/v1/store-auth
  • POST /wp-json/wplp-react-gdpr/v1/upload-logo

これらのリクエストがすべて記録されていれば、攻撃者がサイトに到達した証拠になる。アクセスログはサーバー会社の管理パネルや、レンタルサーバーのログ保存機能から取得できる。ログの保存期間が短いと痕跡が消えるため、普段から長めに保存する設定にしておくことが重要だ。

マルウェアスキャナーでファイルを検査する

サーバーに導入されているマルウェアスキャナーや、WordPress用のセキュリティプラグインを使って wp-content ディレクトリ全体をスキャンする。特に「*.jpg.php」のような二重拡張子のファイルや、最近改変されたPHPファイルが検出対象になる。

スキャナーは攻撃直後の未知のマルウェアを検出できないこともあるが、時間が経ってから見つかることも多い。複数のスキャナーを併用すると検出率が上がる。手動で確認する場合は、wp-content/uploads 以下のファイルで、画像に見せかけたPHPファイルが残っていないかを調べる。

テーマとプラグインの改ざんを確認する

攻撃者はすでに侵入に成功している場合、バックドアを別の場所に仕込んでいる可能性がある。アクティブなテーマの functions.php や、プラグインのディレクトリに不審なコードが追加されていないかを確認する。特に、難読化されたコードや、外部と通信する関数(file_get_contents、curl、eval など)が含まれている場合は注意が必要だ。

再発を防ぐための設定

再発を防ぐための設定

今回の攻撃は特定のプラグインに依存しているが、同種の攻撃は他のプラグインでも発生する。サイト全体の防御力を上げるために、次の設定を検討する。

REST APIのユーザー一覧取得をブロックする

攻撃の第一段階では、WordPress標準のREST APIからユーザー一覧を取得して管理者のユーザー名を特定している。このエンドポイントを無効化するか、ログイン済みユーザーに限定すれば、攻撃の難易度を上げられる。

子テーマの functions.php に次のコードを追加すると、未認証のユーザー一覧取得を防げる。

add_filter( 'rest_endpoints', function( $endpoints ) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'] );
    }
    return $endpoints;
} );

このコードはユーザー一覧のエンドポイントそのものを削除するため、ログイン中でも一覧を取得できなくなる。一部のプラグインがこの機能を使っている場合は影響を確認してから適用する。

アクセスログを長期間保存する

攻撃の痕跡は時間が経つと消える。サーバーのアクセスログを最低でも数週間、可能なら数ヶ月保存しておくと、侵害の調査や再発防止に役立つ。レンタルサーバーの標準設定では数日しか保存されないこともあるため、管理パネルやサーバー会社に確認して保存期間を延ばす。

プラグインの選定と更新ポリシーを見直す

Cookie同意プラグインに限らず、インストール数が少ないプラグインでも攻撃対象になる。更新が止まっているプラグインや、あまり知られていない開発元のプラグインを使い続ける場合は、代替手段を検討する。定期的にプラグインの更新を確認し、不要なプラグインは削除する。

よくある質問

WPLP Cookie Consentを使っていないが対策は必要か

今回の脆弱性はこのプラグイン固有のものだが、アップロードディレクトリでのPHP実行を拒否する設定や、REST APIのユーザー列挙対策はどのサイトでも有効な防御策になる。プラグインの更新とサーバー設定の見直しは、サイト全体のセキュリティを底上げする。

更新したのに攻撃された兆候が残っている場合はどうすればいいか

更新してもすでに設置されたマルウェアは消えない。不正な管理者アカウントの削除、マルウェアスキャン、テーマやプラグインの改ざん確認を行い、必要ならバックアップから復元する。確実なのは、クリーンなバックアップに置き換えて、全パスワードを再発行することだ。

アップロードディレクトリのPHP実行を拒否すると何か問題はあるか

通常のWordPressサイトでは、wp-content/uploads にPHPファイルを置く運用は推奨されていない。画像や文書の配信には影響しない。一部の特殊なプラグインやテーマがこの場所にPHPを置く場合は、事前に動作確認を行う。

REST APIを完全に無効化したほうがいいのか

完全な無効化は、ブロックエディタや一部の機能が動作しなくなるため現実的ではない。ユーザー一覧だけを狙ったエンドポイントを制限するか、認証を要求する設定が現実的な落とし所になる。

この記事のポイント

  • WPLP Cookie Consent 4.4.1以前には未認証でファイルをアップロードされる脆弱性がある
  • まずプラグインを4.4.2以上へ更新し、古いバージョンのままにしない
  • wp-content/uploads 内のPHP実行をサーバー側で拒否する
  • 不正な管理者アカウントがないか wp_users を確認する
  • アクセスログとマルウェアスキャナーで侵害の痕跡を調査する
WooCommerce 11.1でREST APIとStore APIが最大42%高速化。ブロック登録スキップの仕組み

WooCommerce 11.1でREST APIとStore APIが最大42%高速化。ブロック登録スキップの仕組み

WooCommerce 11.1がブロック登録の仕組みを大きく変更する。REST APIとStore APIのリクエストが従来より13〜18ミリ秒、割合で30〜42%速くなる見込みだ。

これまでWooCommerceはほぼすべてのリクエストでブロックタイプとパターンを登録していた。画面にブロックを描画しないAPIリクエストでも同じ準備処理が走り、無駄なコストになっていた。

この記事では変更の背景と仕組み、影響を受ける開発者の条件、具体的な対応方法を解説する。11.1は正式リリース前の段階のため、エクステンションを配布している開発者は事前テストが求められる。

なぜブロック登録をスキップするのか

なぜブロック登録をスキップするのか

ほぼ全リクエストで発生していた無駄な処理

WooCommerceはこれまで、ブロックタイプとパターンをほぼすべてのリクエストで登録していた。商品データを返すだけのREST APIリクエストでも、カート情報を返すStore APIリクエストでも、ブロックを描画しないのに登録処理が実行されていた。

ブロック登録にはファイル読み込みやメタデータ解析が伴う。1リクエストあたりの負荷は小さくても、APIを多用する店舗やヘッドレスコマース構成では応答速度に影響する。WooCommerceチームは「リクエストはブロックを描画または編集できる場合にのみ、ブロック登録のコストを支払うべき」という方針を取った。

従来のリクエスト処理(Before)
全リクエスト ブロック登録を実行 ブロック登録 本来の処理
改善後のリクエスト処理(After)
REST API リクエスト ブロック登録を実行しない 登録スキップ 本来の処理

Beforeではすべてのリクエストがブロック登録を経由していた。Afterではブロックを描画しないAPIリクエストが登録処理を飛ばし、その分だけレスポンスが速くなる。

描画しないリクエストに課されるコスト

従来の挙動は、ブロックを編集も描画もしないリクエストまでブロックエディタの準備をさせるものだった。この無駄はアクセス数に比例して増える。とくにモバイルアプリやフロントエンドを別システムで構築し、WooCommerceをAPI経由で使う構成では影響が大きい。

今回の最適化は、APIリクエスト全体に占めるブロック登録のコストが想定以上に大きかったことを示している。13〜18ミリ秒の改善は体感的には小さいが、ピーク時に多数のリクエストを処理する店舗では合計の短縮効果が積み上がる。

11.0から11.1へ段階的に進めた変更

11.0から11.1へ段階的に進めた変更

11.0で導入したパターンの遅延読み込み

第一段階はWooCommerce 11.0で実装された。パターンがファイルパスで登録され、エディタから要求されたときだけ内容が読み込まれるようになった。WordPressコアと同じ挙動だ。ブロックを登録するリクエストごとに5〜8ミリ秒の節約が確認されている。

11.1のBlockRegistrationContextガード

11.1では新しいBlockRegistrationContextガードが追加された。このガードがリクエストを判定し、ブロックを描画しない場面ではブロックタイプとパターンの登録をまとめてスキップする。

商品説明を守るオンデマンド登録の例外

1つだけ例外がある。商品説明やバリエーション説明にWooCommerceブロックが含まれる場合、woocommerce_short_descriptionフィルター経由で必要なときにブロックタイプが登録される。これにより商品REST API、Store API、バリエーションAJAXエンドポイント、商品のWebhookでも説明が正しく描画される。

STEP 1 11.0でパターンの遅延読み込みを導入
STEP 2 11.1でブロック登録をスキップするガードを追加
STEP 3 Store APIとREST APIが13〜18ミリ秒、30〜42%高速化

2段階の変更により、パターン読み込みとブロック登録という2つの重い処理がAPIリクエストから外れた。完成した最適化の効果が30〜42%という数字に表れている。

対象リクエストと安全性の設計

対象リクエストと安全性の設計

スキップ対象と従来どおりのリクエスト

スキップされるのはブロックを描画しないリクエストのみだ。フロントエンド、管理画面、ブロックエディタ、サイトエディタのリクエストは従来どおりブロックを登録する。

見落としがあっても表示は壊れない

ガードは自身が認識したコンテキストだけをスキップする。認識できない場面では登録を継続するため、分類に漏れがあったとしても描画の後退にはつながらない。性能が少し落ちるだけで済む設計だ。

登録をスキップするリクエスト
REST API、Store APIなどブロックを描画・編集しない場面
従来どおり登録するリクエスト
フロントエンド、管理画面、ブロックエディタ、サイトエディタ
認識できないコンテキスト
登録を継続するため、表示が壊れることはない

この設計は保守性の面でも合理的だ。未知のリクエストに対して安全側に倒すため、WooCommerceの内部判断が変わっても既存サイトの表示が突然崩れるリスクを抑えられる。

開発者が確認すべき影響範囲

開発者が確認すべき影響範囲

影響を受けるエクステンションの条件

この変更はWooCommerce 11.1.0から適用される。スキップされるリクエスト中にWooCommerceブロックを描画するエクステンション、またはWooCommerceのブロックタイプ、パターン、ブロックごとのアセット登録に依存するエクステンションが影響を受ける。

スキップされた場面では、WooCommerceブロックは生のブロックマークアップか、動的出力のない静的なHTMLとして返る。テンプレートに直接ブロックを組み込んでいるエクステンションは、表示内容が変わらないか確認が必要だ。

コードで確認する方法

影響の有無はコードで確認できる。以下のコードはWooCommerce 11.1以降のスキップ対象リクエストでfalseを返す。

// WooCommerce 11.1以降、スキップされた場面では false を返す。
WP_Block_Type_Registry::get_instance()->is_registered( 'woocommerce/mini-cart' );

商品説明と自前ブロックは影響なし

商品説明とバリエーション説明はオンデマンドで処理されるため対応は不要だ。register_block_type()で自前登録しているブロックも影響を受けない。今回の変更はWooCommerce自身が行う登録だけが対象になる。

実務では「自前でブロックを登録しているか」「WooCommerceのブロック登録に依存しているか」の切り分けが重要になる。前者は今回の変更を意識する必要がなく、後者だけが対応を検討すればよい。

開発者が取るべき対応と正しいブロック作成

開発者が取るべき対応と正しいブロック作成

woocommerce_should_register_blocksフィルターで復帰

影響を受けるエクステンションは、新しいwoocommerce_should_register_blocksフィルターを使い、実際にブロックを描画するリクエストのときだけtrueを返す。

add_filter(
    'woocommerce_should_register_blocks',
    function ( $should_register ) {
        return my_context_renders_blocks() ? true : $should_register;
    }
);

フィルターはプラグイン読み込み時に実行され、メインクエリが解析される前の段階で呼ばれる。そのため条件には$_SERVER$_GETなど、この初期段階で利用できる情報だけを使うことになる。

復帰させる範囲を絞りすぎるとブロックが見つからず表示が変わることがある。逆に広げすぎると今回の性能改善が失われる。描画が実際に発生するリクエストを正確に判定する条件を書くのが開発者の作業になる。

内部クラスAbstractBlockを避ける

WooCommerceはブロックをAbstractBlockという内部クラスの上に構築しないよう推奨している。内部クラスを継承すると、WooCommerceが下すすべての登録判断、今回のスキップも含めて引き継ぐことになる。

登録の最適化が進むにつれ、内部クラスのライフサイクルは今後も変わり続ける。依存すると将来のアップデートで予期しない挙動になる可能性が高い。

標準のWordPress Block APIを使う

サポートされる方法は標準のWordPress Block APIだ。ブロックをblock.jsonに定義し、init時にregister_block_type()で登録する。カートやチェックアウトの内部ブロックには@woocommerce/extend-cart-checkout-blockテンプレートがある。

WooCommerceの公式ドキュメントにあるスキャフォールディングとサンプルストアデータ、@wordpress/create-blockも出発点として適している。標準APIに沿って作れば、今後の最適化に追随しやすい。

正式リリース前の段階で、WooCommerceはエクステンション開発者に11.1へのテストを呼びかけている。とくに商品データやカート情報をAPIで扱う拡張を配布している場合は、早めの動作確認が安全だ。

この記事のポイント

  • WooCommerce 11.1はブロックを描画しないリクエストでブロック登録をスキップする
  • Store APIとREST APIは13〜18ミリ秒、割合で30〜42%高速化する
  • 商品説明や自前登録ブロックは影響を受けず対応不要
  • 影響を受ける場合のみ woocommerce_should_register_blocks フィルターで復帰させる
  • 内部クラスAbstractBlockではなく標準のWordPress Block APIでブロックを作る
Product Feed PROでブランド・変動商品・商品カテゴリが出力されない時の直し方

Product Feed PROでブランド・変動商品・商品カテゴリが出力されない時の直し方

Product Feed PRO for WooCommerceでブランド・変動商品・Google商品カテゴリがXMLに出力されない場合、まず確認すべきはフィールドマッピングの重複定義とキャッシュの遅延だ。症状が3つ同時に出ていても原因はそれぞれ別で、マッピング設定と条件設定を正しく組み替えれば大半は解決する。

ブランドがXMLに間欠的に出力される原因

ブランドがXMLに間欠的に出力される原因

同じブランドを割り当てた商品の一部にだけ<g:brand>が出力されない場合、最も多いのが「ブランドの取得ソースが複数存在している」ケースだ。WooCommerceの商品編集画面ではブランドが正しく見えていても、フィードプラグインは別のソースを参照して空の値を受け取ることがある。

Product Feed PROにはブランドを取得するための選択肢が複数用意されている。商品ブランド(product_brand)タクソノミー、商品属性(pa_brand)、YITH Brandプラグイン用の「Brand」、WooCommerce Brandsプラグイン用の「Product brand」などが代表だ。これらが混在していると、商品Aはタクソノミーから値を取得し、商品Bは未設定の商品属性を参照して空振りする、という動きになる。

特に複数のプラグインを併用していたり、過去にブランド管理の方法を変更したサイトで起きやすい。商品一覧のCSV書き出しでブランド列を確認すると、同じブランド名でも保存されている場所が商品によって異なるのがわかる。

Before フィールドマッピングが「ブランド(属性)」を参照
商品A Dr Coffee → タクソノミーに設定済み → 実は属性も選択済み → 出力OK
商品B Dr Coffee → タクソノミーに設定済み → 属性は未設定 → 出力なし
After マッピングを「商品ブランド(product_brand)」に統一
商品A Dr Coffee → タクソノミーから取得 → 出力あり
商品B Dr Coffee → タクソノミーから取得 → 出力あり
ブランドの出力がない状態  修正後

このデモは、ブランドの取得ソースを属性にしたままタクソノミーのみ設定した商品で出力が欠落する状況を示している。対処は連載の後半でまとめて説明する。

商品ごとにブランドの保存場所を確認する

WooCommerceの商品一覧からCSVを書き出し、ブランドのタクソノミー列と属性列の両方を確認する。片方だけに値が入っている商品があれば、その商品群で出力が欠落しているはずだ。同じブランド名を保ったまま、フィードが参照するソースにデータを揃える必要がある。

フィードプラグインのフィールドマッピングを再定義する

フィードのフィールドマッピング画面で、<g:brand>フィールドの「取得ソース」を確認する。プルダウンに複数のブランド候補が並んでいたら、実際に価値が入っているタクソノミー(product_brand)を選択し直し、フィードを再生成する。

変動商品がフィードから完全に欠落する原因

変動商品がフィードから完全に欠落する原因

変動商品(バリエーションを持つ商品)がXMLに一切出力されない場合、最初に確認するのは「デフォルトのバリエーション」の設定だ。WooCommerceの変動商品では「デフォルトのバリエーションを選択」プルダウンが「デフォルトを選択」のままになっていると、親商品がフィードの出力対象から外れることがある。

フィードプラグインの設定で「商品のバリエーションを含める」を有効にしても、親商品のバリエーション自体が正しく構築されていないと出力はできない。各バリエーションに価格・在庫状況・画像が設定されているか、親商品がカタログに表示される設定になっているかも重要なチェックポイントだ。

Before デフォルトのバリエーションが未選択
Dr Coffee M10(変動商品)
プルダウン「デフォルトを選択」のまま → フィード生成スキップ
バリエーション3点も非出力
After デフォルトのバリエーションを明示的に選択
Dr Coffee M10(変動商品)
プルダウンで1件選択 → フィードに親商品とバリエーションが出力
価格と在庫のある3バリエーションも表示
フィード欠落の状態  修正後

このデモは、デフォルトのバリエーション未選択で変動商品が出力から漏れる典型的なパターンを表している。ほかに価格未入力や在庫切れでも同様の欠落が起こる。

バリエーションの設定を一括で点検する

変動商品の編集画面で、各バリエーションに通常価格またはセール価格が登録されているか、在庫ステータスが「在庫あり」または「予約可能」になっているかを確認する。バリエーションが「非公開」や「カタログに表示しない」になっていないかも見る。

親商品の「商品データ」メタボックスでは、プルダウンで「デフォルトのバリエーション」を必ず1つ選ぶ。この操作が済んでいない変動商品は、フィードプラグイン側の設定に関係なく出力対象外になるケースが多い。

フィード設定の「商品のバリエーションを含める」を再確認する

Product Feed PROのフィード編集画面で、変動商品に関するオプションが有効か確認する。「商品のバリエーションを含める」と「親商品も含める」の両方が目に入るが、どちらか一方だけ有効になっていると期待した出力にならない。特に親商品を表示するには、その商品自体がカタログに表示される設定である必要がある。

Google商品カテゴリが出力されない原因

Google商品カテゴリが出力されない原因

Google商品カテゴリ(<g:google_product_category>)がXMLに出ない場合、原因はほぼ「カテゴリマッピングの条件不一致」か「フィールドマッピングの取得ソースにgoogle_categoryが設定されていない」のどちらかだ。カテゴリマッピング画面でWooCommerceカテゴリとGoogleカテゴリを紐づけただけでは、フィードに反映されない。

カテゴリマッピングの画面では、左側にWooCommerceの商品カテゴリ、右側にGoogleの商品カテゴリを割り当てる。この割り当てが「すべてのカテゴリ」ではなく、一部のカテゴリだけに適用される条件で作られていると、対象外のカテゴリに属する商品からはカテゴリが出力されない。

Before カテゴリマッピングに条件絞り込みが残っている
WooCommerceカテゴリ「コーヒーマシン」だけにGoogleカテゴリを割り当て
→ 他のカテゴリ(ドリップ用品など)は<g:google_product_category>が空のまま
After 全カテゴリを割り当て直し、条件を解除
全WooCommerceカテゴリに対応するGoogleカテゴリをマッピング
→ すべての商品に<g:google_product_category>が出力
カテゴリ未出力  修正後

このデモは、カテゴリマッピングの条件漏れで一部商品のGoogleカテゴリが空になる状況を示している。カテゴリマッピング画面は商品数が多いほど設定漏れが起きやすいので、全カテゴリを対象にするのが基本だ。

フィールドマッピングでgoogle_categoryが設定されているか確認する

フィードのフィールドマッピング画面で、Google側の<g:google_product_category>フィールドに対して、取得ソースが「google_category」になっていることを確認する。このソースは、カテゴリマッピング画面で定義した対照表を参照する専用の値だ。

誤って商品カテゴリそのものを割り当てていると、Googleが求める形式(例: Home & Garden > Kitchen & Dining > Coffee Makers)ではなく、WooCommerceのカテゴリ名だけが出力される。Google Merchant Center側でエラーまたは警告になるため、ソース設定は丁寧に見直す必要がある。

カテゴリマッピングを全カテゴリに適用する

カテゴリマッピング画面で、WooCommerceの各カテゴリに対応するGoogleカテゴリをすべて埋める。カテゴリが多い場合は「未マッピングのカテゴリ」フィルタを使うと、設定漏れのカテゴリだけを洗い出せる。親カテゴリを割り当てたら、子カテゴリが自動的に引き継がれるかどうかも確認する。

3つの問題をまとめて修正する手順

3つの問題をまとめて修正する手順

3つの問題が同時に起きている場合は、それぞれを個別に直すよりも、フィードの基本設定を順番に整える方が早い。次の手順でフィールドマッピング、変動商品設定、カテゴリマッピングを見直す。

STEP 1 ブランドの取得ソースを「商品ブランド(product_brand)」に統一する
STEP 2 変動商品のデフォルトバリエーションを1つ選択する
STEP 3 Google商品カテゴリを全カテゴリに割り当てる
STEP 4 フィードを再生成し、XMLで各フィールドの出力を検証する

このデモは、3つの症状をまとめて修正する際の優先順位を表している。ブランドの取得ソースを先に統一すると、変動商品とGoogleカテゴリの修正結果をXMLで正確に確認できる。

フィード再生成とキャッシュの扱い

設定を変更したあとは、フィードプラグインの「再生成」または「今すぐ更新」ボタンを実行する。WooCommerceやサーバー側のキャッシュが効いていると、更新前のXMLが表示され続けることがある。キャッシュプラグインを使っている場合は、フィードを再生成する前にキャッシュを削除すると確実だ。

生成されたXMLをブラウザで開き、<g:brand><g:google_product_category>、変動商品のIDやタイトルが表示されているかをCtrl+F(MacではCommand+F)で検索する。変動商品は親商品とバリエーションが別々の<item>要素として出力されるため、商品IDではなく商品名の一部で検索すると見つけやすい。

よくある質問

ブランドの出力が安定しないのはキャッシュが原因か?

キャッシュだけが原因になる場合は少ない。ブランドタクソノミーと商品属性の両方に同名のブランドが存在し、フィードのマッピングが不安定なソースを参照していることが多い。キャッシュを削除しても再発するなら、取得ソースの統一が先だ。

変動商品だけがXMLから消えるのはなぜか?

変動商品は親商品と各バリエーションが個別の商品として扱われるため、単純商品より出力条件が厳しい。デフォルトのバリエーション未選択、価格未入力、在庫切れ、または「商品のバリエーションを含める」設定のミスが典型的な原因になる。

Google商品カテゴリの出力形式が正しいか確認する方法は?

出力されたXML内の<g:google_product_category>の値を確認し、Google Merchant Centerが求める形式(不等号で区切られた英語の数字付きカテゴリパス)になっているかを見る。WooCommerceのカテゴリ名だけが入っている場合は、フィールドマッピングの取得ソースが誤っている。

設定を変えてもフィードが更新されない場合は?

フィードの再生成ボタンを押したあと、ブラウザでXMLを開いたときに古い内容が表示されることがある。キャッシュプラグインの削除、サーバー側のキャッシュ(OPcacheやVarnish)のクリア、またはクエリパラメータを付けて開く(例: feed.xml?nocache=1)と最新の出力を確認できる。

ブランドが空の商品はどうやって特定するか?

WooCommerceの商品一覧でフィルタ機能を使い、ブランドタクソノミーが空の商品を絞り込む。もし全商品にブランドが付いているのにXMLには一部しか出ていないなら、取得ソースの不一致を疑う。CSV書き出しでブランド列とブランド属性列を並べて比較すると特定しやすい。

この記事のポイント

  • ブランドは取得ソースの統一が最優先
  • 変動商品はデフォルトバリエーションの選択が必須
  • Google商品カテゴリは全カテゴリのマッピングが必要
  • 設定変更後はキャッシュを削除して再生成する
  • XMLを検索して各フィールドの出力を検証する
Googleサーチコンソールの生成AIレポートが全世界展開。見方とオプトアウトの注意点

Googleサーチコンソールの生成AIレポートが全世界展開。見方とオプトアウトの注意点

Googleサーチコンソールの生成AIレポートが、2026年8月31日付で全世界のサイトに展開された。AI OverviewsやAI Modeなど生成AI機能での表示回数を、ページ別・国別・日付別に確認できる。

一方で、クリックデータはまだ提供されていない。表示はされても実際のサイト訪問につながったかは分からない。この記事ではレポートの見方、オプトアウト設定の仕組み、SEO担当者が取るべき対応を整理する。

生成AIレポートの全体像

生成AIレポートの全体像

2026年6月から段階的に展開が始まった生成AIレポートは、8月31日付の公式注記で全世界のサイトに行き渡った。Search Consoleにログインすると、検索レポートとDiscoverレポートのそれぞれで生成AI関連のデータを確認できる。

レポートが対象とするのは、AI Overviews、AI Mode、Discoverの生成AI機能だ。AI Overviewsは検索結果の上部に生成AIが回答の要約を表示する機能を指す。AI Modeは対話形式で検索を続けられる専用モードだ。DiscoverはGoogleアプリのフィードで、ここにも生成AIによるコンテンツ表示が含まれる。

従来の検索フロー(Before)
ユーザー キーワード検索 検索結果ページ サイトをクリック サイト訪問
※クリックが発生し、実際のトラフィックにつながる
生成AI検索のフロー(After)
ユーザー 自然言語で質問 AI Overviews 等 回答を表示 サイトはインプレッションのみ
※表示はされるが、クリックされるとは限らない

従来の検索ではクリックが発生してサイト訪問につながっていた。生成AI検索ではサイトが回答の参照元として表示されても、ユーザーがクリックするとは限らない。この違いがレポートの重要性を高めている。

レポートで確認できる指標

レポートには生成AI機能での表示回数、つまりインプレッションが記録される。検索レポートではページ別・国別・日付別に加えて、デバイス別の内訳も確認できる。Discoverレポートでも同様に、ページ・国・日付の切り口でデータを見られる。

たとえば、自社の記事がAI Overviewsの中でどの国で多く表示されているか、日を追って伸びているかを把握できる。特定のページが頻繁に参照されているなら、その分野のコンテンツが生成AIに評価されている可能性を示す。

クリックデータは含まれない

公開時点でレポートにクリックデータは含まれていない。クリック数やクリック率は確認できず、表示が実際のサイト訪問につながったのかは分からない。この制約は、レポートの活用方法を考えるうえで大きなポイントになる。

Googleはアクセスについても、すべてのプロパティに展開が完了したわけではないとヘルプページで説明している。AIインプレッションが十分に蓄積されていないサイトでは、レポート自体が表示されない可能性がある。

オプトアウト設定の仕組み

オプトアウト設定の仕組み

レポートと同時に提供されているのが「Search generative AI control」というオプトアウト設定だ。Search Consoleの設定画面に配置されており、プロパティ単位で有効にできる。この設定を使うと、AI Overviews、AI Mode、Discover生成AIの3つの表示面からサイトのリンクとコンテンツを除外できる。

オプトアウトしたサイトは、これらの生成AI機能からのトラフィックとインプレッションが一切発生しなくなる。Googleは公式発表で、この設定が通常の検索ランキングのシグナルとして使われることはないと明言している。生成AI機能に表示されないことが、通常の検索順位に影響することはないという意味だ。

レポートとオプトアウトが対象とする3つの表示面
AI Overviews 検索結果の上部に表示される生成AIの回答要約
AI Mode 対話形式で検索を続けられる生成AI専用モード
Discover 生成AI Discoverフィード内に表示される生成AIによるコンテンツ

レポートはこの3つの表示面を対象にインプレッションを集計する。オプトアウト設定も同じ3面が対象になるため、運用の判断ではこの対応関係を理解しておきたい。

設定の効果と影響範囲

オプトアウトはプロパティ単位で適用される。つまり、サイト全体がまとめて生成AI機能から除外される形だ。ページ単位で一部だけ除外するような細かい制御は、現時点では提供されていない。

除外を有効にすると、生成AI機能からの表示は完全に止まる。生成AI経由の露出をすべて断つことになるため、ブランド認知や間接的な流入を期待している場合は慎重な判断が求められる。

AIトレーニングとは別の設定

このオプトアウトは、生成AIの学習データへの利用を制御する仕組みとは別物だ。Googleの生成AIトレーニングへの利用可否は、Google-Extendedという別の制御で管理される。Search generative AI controlを有効にしても、AIトレーニングへの利用は止まらない。

「生成AI機能への表示」と「AIの学習利用」は異なる設定で管理されている。SEO担当者は、この2つを混同せずに運用方針を決める必要がある。

ここまでの展開経緯

ここまでの展開経緯

生成AIレポートとオプトアウト設定は、2026年6月3日にGoogleから同時に発表された。当初は英国のウェブサイト運営者の一部を対象にした限定的なテストとして始まっている。

同日、英国の競争・市場庁(Competition and Markets Authority / CMA)は行動要件を発行した。Googleに対し、サイトが通常の検索結果でペナルティを受けることなくAI検索機能からオプトアウトできるようにすることを求めた。

6月の発表と英国限定テスト

6月の時点では、レポートとオプトアウト設定は英国の選ばれたサイト運営者にのみ提供された。規制当局の要求と同時期に動き出した形だ。検索市場における競争環境を意識した展開だったといえる。

7月以降の段階的な拡大

7月になると、英国以外のアカウントでも設定が表示され始めた。その後、8月31日付の注記で全世界のサイトへの展開が完了したとされた。ただし、ヘルプページには展開が進行中であるとの記載が残っており、実際のアクセスにはタイムラグがあるようだ。

なぜ重要なのか

なぜ重要なのか

レポートが見えるようになると、オプトアウトを判断する前に生成AI機能での表示状況を確認できる。これまではブラックボックスだったAI検索内での露出が、数字として見えるようになる。

ただし、インプレッションの真の価値はまだ明確ではない。表示回数が多くても、クリックにつながるかどうかは別の問題だ。生成AI検索では、ユーザーが回答だけで満足してサイトを訪れないケースが増えると指摘されている。

レポートで見えるデータ
ページ別の表示回数
国別の表示回数
日付別の表示回数
デバイス別の内訳(検索レポートのみ)
レポートで見えないデータ
クリック数とクリック率
表示からサイト訪問につながった割合
生成AI回答内での引用位置や文脈

レポートで見えるのは表示回数のみ。実際のトラフィック効果を測るにはクリックデータが必要になる。SEO担当者はこの制約を踏まえたうえでデータを読む必要がある。

SEO担当者が取るべき対応

まずはSearch Consoleでレポートの有無を確認する。すでに表示されている場合は、どのページがどの表示面でインプレッションを得ているかを把握できる。AIインプレッションが少ないサイトでは、レポート自体が表示されないこともある。

表示回数が少ない場合や、自社ブランドと合わない文脈で引用されている場合は、オプトアウトを検討する余地がある。ただし、クリックデータがないため、露出を継続した場合の潜在的な影響を過小評価しないことも重要だ。

既存の検索パフォーマンスレポートと併用し、通常検索の推移と生成AI検索の露出を比較しながら総合的に判断する。オプトアウトはプロパティ単位でしか実行できないため、サイト全体への影響を考慮する必要がある。

インプレッションデータの限界

最大の限界は、クリック数が分からない点だ。表示回数が増えても、サイトへの訪問が増えていなければビジネス上の価値は低い。生成AI回答にサイトの情報が引用されても、ユーザーがリンクを押さなければ意味がない。

加えて、引用位置や文脈も確認できない。自社サイトが回答の根拠として適切に扱われているのか、単に名前が出ているだけなのかをレポートから読み取ることはできない。インプレッションの質を評価する材料が不足しているのが現状だ。

今後の展望

今後の展望

CMAは2027年3月までに、ページ単位の生成AI機能コントロールを導入するようタイムラインを設定している。現在のプロパティ単位の設定より細かい制御が求められている。

規制当局はクリックデータの提供も期待している。しかし、8月31日の更新ではクリックレポートへの言及はなかった。クリックデータが追加されれば、レポートの実用性は大きく高まる。

CMAの要求とタイムライン

ページ単位のコントロールは、サイト全体ではなく特定のページだけを生成AI機能から除外できる仕組みを指す。これが実現すれば、オプトアウトの判断がより柔軟になる。生成AI経由の露出を活かしたいページと、除外したいページを分けて運用できるようになる。

クリックデータ提供の行方

クリックデータが追加されるかは、現時点では未定だ。Googleは最初の1年間、コンプライアンス状況を6か月ごとに報告する義務を負っている。規制当局の継続的な監視が、レポートの改善を後押しする可能性は高い。

この記事のポイント

  • 生成AIレポートは2026年8月31日付で全世界のサイトに展開された
  • 対象はAI Overviews、AI Mode、Discover生成AIの3面で、ページ別・国別・日付別に表示回数を確認できる
  • クリックデータはまだ提供されておらず、表示がトラフィックにつながるかは分からない
  • オプトアウトはプロパティ単位で、検索ランキングには影響しないとGoogleが明言している
  • CMAは2027年3月までにページ単位のコントロールを要求しており、今後の仕様変更に注意が必要
カートページで数量を変更すると違う数になる時の対処法

カートページで数量を変更すると違う数になる時の対処法

WooCommerceのカートページで数量を1から2に変更したのに3が表示される不具合は、テーマまたはプラグインの古いJavaScriptが原因で数量更新のイベントが二重に処理されるケースが多い。まずテーマとWordPress本体・WooCommerceを更新し、それでも直らなければプラグインの競合を切り分けるのが最短の解決手順だ。

なぜカートページの数量変更で数がずれるのか

なぜカートページの数量変更で数がずれるのか

カートページで数量を変更すると、WooCommerceはAjax通信でサーバーに更新を送り、その結果を画面に反映する。このときブラウザ側のJavaScriptが「変更前の数量」と「変更後の数量」を正しく引き算して表示する仕組みになっている。

ところがテーマやプラグインが古いjQueryや独自のAjax処理を持っていると、同じクリックや入力イベントに対して数量加算の処理が2回走ることがある。たとえば「1を2に変更」が「1を3に変更」として解釈され、画面に3が表示される。

特に数量に小数を許可するプラグイン(WooCommerce Decimal Productなど)が有効な場合、数量フィールドの値の扱いが標準と変わるため、テーマ側のJavaScriptとの相性問題が表面化しやすい。プラグインを無効化すると正常になることから、原因がプラグイン単体でなく「プラグインとテーマの組み合わせ」にあると判断できる。

テーマとWordPressを最新版に更新する手順

テーマとWordPressを最新版に更新する手順

この不具合は、テーマ・WordPress・WooCommerceのいずれかが古いことで、最近のブラウザやプラグインとの間でJavaScriptの仕様差が生じるために起きることがある。まずは更新作業から始める。

STEP 1 サイト全体のバックアップを取る
STEP 2 WordPress本体・テーマ・WooCommerce・全プラグインを更新する
STEP 3 キャッシュプラグインのキャッシュを全削除する
STEP 4 カートページで数量を変更して動作確認する

更新後はシークレットウィンドウや別ブラウザでテストする。通常のブラウザに古いCookieやキャッシュが残っていると、修正後も古いJavaScriptが動いてしまうためだ。

JavaScriptの競合を切り分ける手順

JavaScriptの競合を切り分ける手順

更新しても症状が変わらない場合、特定のプラグインやテーマのJavaScriptがWooCommerceの数量更新イベントと競合している。原因を特定するには「無効化テスト」が確実だ。

プラグインを1つずつ無効化して原因を特定する

まずプラグイン一覧から、数量に関係するプラグイン(小数プラグイン・カスタム数量プラグイン・Ajaxカートプラグインなど)を候補として絞り込む。それぞれ無効化してカートページを再読み込みし、数量が正しく更新されるか確認する。

もし特定のプラグインを無効化したときだけ正常になるなら、そのプラグインが原因だ。プラグインの更新版が出ていないか確認し、出ていなければ代替プラグインへの乗り換えを検討する。

ブラウザのコンソールでJavaScriptエラーを確認する

ブラウザのデベロッパーツール(ChromeではF12キー)を開き、「Console」タブを確認する。カートページで数量を変更したときに赤いエラーが表示される場合、エラーのファイル名から競合元を特定できる。

エラーメッセージが「jQuery is not defined」や「$ is not a function」なら、テーマのJavaScriptがjQueryを正しく読み込んでいない。wp_enqueue_script の順序や依存関係の問題なので、テーマ制作者に修正を依頼するか、子テーマ側で読み込みを調整する。

「cart-fragments」や「wc-cart-fragments」に関するエラーなら、WooCommerceのAjaxカート更新機能が別のプラグインと衝突している。該当プラグインを特定して無効化すれば症状は収まる。

キャッシュとCookieの影響を排除する

キャッシュとCookieの影響を排除する

修正後も古い表示が続く場合は、サーバー側のキャッシュとブラウザ側のCookieが原因で古いJavaScriptが読み込まれている可能性がある。キャッシュプラグイン(WP Super Cache、W3 Total Cache、LiteSpeed Cacheなど)のキャッシュを全削除し、ブラウザのCookieとキャッシュも消去してから再テストする。

また、CDN(Cloudflareなど)を利用している場合は、CDN側のキャッシュもクリアする。CDNが古いJavaScriptファイルを配信し続けると、サーバー上では更新済みでもブラウザには古いコードが届く。

よくある質問

数量が正しく更新されるか確認する方法は?

カートページで数量を複数回変更し、そのたびにカート内の小計と合計が正しく再計算されるかを確認する。加えて管理画面の「WooCommerce→ステータス→ログ」にJavaScript関連のエラーが記録されていないか確認するとよい。

テーマを更新しても大丈夫?

更新前にバックアップを取っていれば問題ない。カスタマイズをテーマ本体に直接書いている場合は、更新で消える可能性があるので、子テーマや独自プラグインに移してから更新するのが安全だ。

小数プラグインを使い続けながら直す方法は?

プラグイン自体に更新版がない場合は、テーマ側のJavaScriptを修正して競合を回避する必要がある。具体的にはカートページの数量更新をWooCommerce標準のAjax処理に任せるよう、テーマのcustom.jsmain.jsから数量関連のコードを除去する。

テストサイトを作るべき?

本番サイトに影響を与えずに原因を切り分けたい場合は、ステージング環境(多くのレンタルサーバーに標準搭載)か、ローカル環境(LocalやXAMPPなど)で同じテーマとプラグインを再現するのが有効だ。テストサイトで症状が再現できれば、切り分け作業を安全に進められる。

PHPのバージョンは関係ある?

PHPのバージョンが極端に古い(7.4未満など)場合、WooCommerceの最新版が正しく動作しないことがある。サーバー管理画面でPHP 8.0以上に更新できるか確認するのも有効な切り分けのひとつだ。

この記事のポイント

  • カートの数量が「1→2」で「3」になるのはJavaScriptの二重処理が主因
  • テーマ・WordPress・WooCommerceの更新で解決するケースが多い
  • 直らない場合はプラグインを1つずつ無効化して競合元を特定する
  • ブラウザとサーバーのキャッシュ・Cookie削除を忘れない
  • 小数プラグインを使うならテーマ側のJavaScript競合を重点確認する
Rank Mathプラグインが管理者権限を無断取得か。WordPressセキュリティ問題

Rank Mathプラグインが管理者権限を無断取得か。WordPressセキュリティ問題

Rank Mathプラグインに重大なセキュリティ懸念が持ち上がっている。無料アカウントに連携した状態で「ヘルプ&サポート」セクションを開くと、管理者権限を持つアプリケーションパスワードが無断で生成されるという指摘が、開発者コミュニティからあがった。

指摘したのは、競合するThe SEO Frameworkプラグインの開発者Sybre Waaijer氏だ。Rank Mathは400万以上のサイトで利用される人気プラグインであり、影響範囲は極めて広い。今回はこの問題の仕組みと、サイト運営者が取るべき対処法を整理する。

Rank Mathの方式(Bad・無承認)
Rank Math ヘルプ&サポートを開く 無断でパスワード生成 外部サーバーへ送信
※ユーザーに承認を求めない。規約ボックスは表示されるが生成は止まらない。
WordPress公式の方式(Good・承認プロセス)
プラグイン 接続要求を表示 ユーザーが承認 パスワード生成
※承認画面で許可してから初めてパスワードが渡される。

このデモは、Rank Mathが取っているとされる方式と、WordPress公式が定める方式の違いを図式化したものだ。無承認での生成が問題の核となっている。

Rank Mathプラグインに何が起きているのか

Rank Mathプラグインに何が起きているのか

指摘の発端と具体的な動作

2026年8月30日、Search Engine JournalはRank Mathプラグインに関する新たな疑惑を報じた。The SEO Frameworkの開発者Sybre Waaijer氏が、Rank Mathの「ヘルプ&サポート」セクションを開くだけで管理者権限が外部に渡ると指摘したのだ。

Waaijer氏によれば、Rank Mathは1.0.277へのアップデートでセキュリティ問題を修正した。しかし同じアップデートに、group.one(WP Rocketの所有者でもある企業)がサイトの管理者権限を取得できる機能が含まれていたという。

対象となるファイルは vendor/groupone/wap-client/includes/class-app-password-manager.php だ。無料のrankmath.comアカウントに接続されたサイトで、管理者が「ヘルプ&サポート」を開くと、プラグインが即座に「WAP – Rank Math Support Agent」という名前のアプリケーションパスワードを生成する。そのパスワードはgroup.oneのサーバーへ送信され、同社のAIエージェントがユーザーに代わってサイトを操作できる状態になる。

許可なき権限委譲という問題

Waaijer氏は「プラグインは最初にユーザーへ確認しない。「利用規約」ボックスは表示されるが、パスワードの生成と送信を止めることはできない。送信はボックスが表示される前に始まっている」と説明している。

つまりユーザーは、何の操作もしないうちに、自分のサイトの管理者権限を第三者へ委譲してしまう。しかも、その事実を知らされることはない。ヘルプ&サポートを閉じてもパスワードは失効せず、無期限に有効なままだ。

影響範囲と深刻度

Rank Mathは400万以上のサイトで利用されている。管理者権限があれば、プラグインの更新、テーマの変更、投稿の削除、ユーザー情報の閲覧といった、サイト運営の中核的な操作が可能になる。これはSEOプラグインの枠を超えた、サイト全体の安全性に関わる問題だ。

問題の中核にあるアプリケーションパスワードとは

問題の中核にあるアプリケーションパスワードとは

WordPress標準の正当な仕組み

WordPressアプリケーションパスワードは、WordPressコアに含まれる正規の機能である。外部アプリケーションがWordPressサイトへ安全に接続するための仕組みで、ユーザーはいつでも個別に取り消せる。プラグインがこの仕組みを利用すること自体は、公式に認められている。

重要なのは、公式の仕様ではアプリケーションパスワードを発行する前に、必ず承認画面が表示されることだ。ユーザーがプラグインの身元を確認し、接続を許可するか拒否するかを選べる。パスワードがプラグインに渡るのは、ユーザーが承認した後でなければならない。

Rank Mathがガイドラインから外れている点

Rank Mathの動作は、この公式プロセスを完全に飛ばしている。承認画面は表示されず、ユーザーが何かをクリックする前にパスワードが生成され、外部サーバーへ送信される。Waaijer氏が指摘する通り、過去に同氏が「バックドア」と分類したものと構造が似ている。

WordPress.orgのプラグインガイドラインでは、外部サーバーと通信する際にはユーザーの明示的な同意が必要だと定められている。オプトインのチェックボックスや、サービスへの登録を経た同意が求められるのだ。Rank Mathの実装は、この原則に真っ向から反している。

取り消し方法が明示されない

アプリケーションパスワードは本来、ユーザーが確認して取り消せることを前提にしている。しかしRank Mathの場合、「ヘルプ&サポート」を開いただけでは、パスワードが発行された事実に気づく手がかりがない。プロフィール画面に「WAP – Rank Math Support Agent」という名前で表示されるため、知っていれば探せるが、知らなければ発見は難しい。

ユーザーコミュニティの反応

ユーザーコミュニティの反応

ソーシャルメディア上の反応は、一貫して否定的だった。一部のユーザーはWordPressコアにSEO機能を統合すべきだと主張し、別のユーザーはRank Mathから別のSEOプラグインへ移行する意思を示した。

フォーラムスレッド削除の疑惑

議論の中で、Rank Mathの公式フォーラムに大きなスレッドが立っていたが、その後削除されたという報告もあった。ユーザーの一人は「数日前にフォーラムで大きなスレッドが立っていたが、今日削除通知が来た。ユーザーフォーラムが大荒れになった後に削除されたようだ」と述べている。

もし事実なら、これはコミュニティの懸念を正面から受け止めていない姿勢と映る。透明性を求める声に対して、静かな対処を選んでいるように見えるからだ。

ユーザーが感じている不信感

「管理者アクセスが無断で?」という短い反応に、多くのユーザーの驚きが凝縮されている。SEOプラグインは検索順位を改善するための道具であって、サイトの制御権を委譲するものではない。誰もがそう考えていたからこそ、今回の発覚は衝撃を持って受け止められた。

Rank Mathの過去の脆弱性と信頼性

Rank Mathの過去の脆弱性と信頼性

脆弱性の履歴

Rank Mathは2024年に7件、2025年に4件、2026年に入って3件の脆弱性が発見されている。直近では、認証されていない状態で保存型クロスサイトスクリプティング(XSS)を実行される脆弱性も報告されていた。

1つのプラグインにこれだけの脆弱性が続くこと自体が、セキュリティ管理の甘さを示す。その上に今回の無断権限取得が加われば、信頼はさらに揺らぐ。

Search Engine Journalの推奨リストから外れている

Search Engine Journalは、自社の推奨WordPressプラグインリストにRank Mathを含めていない。推奨条件の1つが「脆弱性の履歴がないこと」であり、Rank Mathはこの基準を満たせていないためだ。

プラグインの選択では、機能の豊富さだけでなく、セキュリティ面の信頼性を確認することが重要になる。今回の件は、その判断基準を改めて浮き彫りにした。

WordPressサイト運営者が取るべき対処法

WordPressサイト運営者が取るべき対処法

まずはパスワードを取り消す

Rank Mathを利用していて、無料アカウントに接続した状態で「ヘルプ&サポート」を開いたことがあるなら、すぐにアプリケーションパスワードを取り消すべきだ。Waaijer氏が具体的な手順を示している。

  • WordPress管理画面の「ユーザー」から「プロフィール」を開く
  • 「アプリケーションパスワード」セクションを確認する
  • 「WAP -」で始まるパスワードをすべて取り消す

この操作により、Rank Mathのサポートエージェントが保持している管理者権限を無効化できる。手順は数分で済むが、放置すればリスクは残り続ける。

接続解除と設定の見直し

Rank Mathアカウントとの接続を解除することも有効な対策だ。接続していなければ、ヘルプ&サポートを開いてもパスワードは生成されない。必要になるまで無料アカウントへの接続を切っておくのが無難だ。

また、プラグインの権限設計そのものを見直す機会にしてほしい。管理者以外のユーザーがプラグイン設定を触れるようになっていないか、不要なプラグインが残っていないかを確認する。サイトのセキュリティは、積み重ねた小さな確認で守られる。

他プラグインの移行を検討する

今回の件を受けて、別のSEOプラグインへの移行を検討するユーザーも増えている。The SEO FrameworkやYoast SEOなど、信頼性の高い選択肢は複数ある。重要なのは、移行前に既存の設定やリダイレクト情報をバックアップしておくことだ。

取るべきステップ
STEP 1 アプリケーションパスワードを確認して「WAP -」をすべて取り消す
STEP 2 Rank Mathアカウントとの接続を解除する
STEP 3 プラグインの権限設定とユーザー権限を見直す
STEP 4 別のSEOプラグインへの移行を検討する

上記のステップを順に実行することで、無断で付与された権限を無効化し、今後のリスクを低減できる。最初のステップが最も緊急性が高い。

この記事のポイント

  • Rank Mathはヘルプ&サポートを開くと管理者権限のアプリケーションパスワードを無断生成すると指摘された
  • 承認画面なしでパスワードが外部サーバーへ送信される仕組みはWordPress公式ガイドラインに違反する
  • Rank Mathは2024年から2026年にかけて合計14件の脆弱性が報告されている
  • 利用者は「ユーザー → プロフィール → アプリケーションパスワード」から「WAP -」をすべて取り消すべき
  • アカウント接続の解除と他SEOプラグインへの移行も有効な対策になる
WP to Hootsuite 3.xで予約投稿が失敗するCronエラーの対処法

WP to Hootsuite 3.xで予約投稿が失敗するCronエラーの対処法

WP to Hootsuite を 3.x 系へ更新したあと、予約投稿が Hootsuite に公開されない場合は、Cron クラスの reschedule_refresh_token_event メソッドが未定義のままになっている可能性が高い。プラグインを 3.1.4 以降へ更新すれば、この致命的エラーは解消する。

なぜWP to Hootsuite 3.xで予約投稿が失敗するのか

なぜWP to Hootsuite 3.xで予約投稿が失敗するのか

この不具合は、プラグインの更新時に必要なメソッド定義がファイルへ正しく反映されず、呼び出しだけが先に組み込まれた状態で発生する。3.x 系では WPZinc 製プラグイン共通の Social ライブラリへ構成が変わったため、一部のファイルに古いコードと新しいコードが混在しやすくなっている。

具体的には、includes/functions.php が Cron クラスの reschedule_refresh_token_event メソッドを呼ぶ一方、lib/social/includes/class-cron.php にそのメソッド定義がない。存在しないメソッドへの呼び出しは PHP の致命的エラーを引き起こし、その後の処理が止まる。

WPZinc\Social\Cron::reschedule_refresh_token_event()

予約投稿の実行は WP-Cron(WordPress の予約実行システム)を経由する。ここで致命的エラーが起きると画面には何も表示されず、プラグイン自身のログ画面にも記録が残らない。管理画面からの手動更新はトークン再スケジュール処理を通らないため成功するので、問題の特定が遅れやすい。

予約投稿が公開されない流れ
予約時刻 WP-Cron が予約投稿を実行する
処理 functions.php が reschedule_refresh_token_event を呼ぶ
エラー class-cron.php に該当メソッドがない
結果 致命的エラーで処理停止、Hootsuite に公開されない
エラー発生箇所  正常な入り口

上の図は、予約投稿が致命的エラーで止まるまでの流れを示している。

プラグインのログ画面が空のままなのは、致命エラーが起きた時点で PHP の処理が停止し、ログを書き込むコードまで到達しないためだ。管理画面からの手動更新ではトークン再スケジュール処理が呼ばれないため、問題なく成功する。

3.1.4以降への更新で解消する手順

3.1.4以降への更新で解消する手順

この不具合はプラグイン側のコード不整合なので、特別な設定変更は不要だ。WP to Hootsuite を 3.1.4 以上へ更新すると、未定義だったメソッドが class-cron.php に追加され、予約投稿の処理が最後まで走るようになる。

更新作業の前に、必ずサイト全体のバックアップを取る。プラグイン更新そのものは数分で終わるが、万一テーマや他プラグインと競合した場合に戻せる状態にしておくことが重要だ。

STEP 1 サイト全体のバックアップを取得する
STEP 2 管理画面のプラグイン一覧で WP to Hootsuite を更新する
STEP 3 バージョンが 3.1.4 以上であることを確認する
STEP 4 失敗した予約投稿を再スケジュールして動作確認する

上のステップは、更新から動作確認までの一連の流れを示している。

更新後はキャッシュ系プラグインの全削除も忘れずに行う。そのうえで、以前に失敗した投稿を一度下書きへ戻すか、公開予定日時を再設定して様子を見ると確実だ。

すぐに更新できない場合はどう対処するか

すぐに更新できない場合はどう対処するか

2.x系へ巻き戻して様子を見る

何らかの事情ですぐに 3.1.4 へ更新できない場合は、動作していた 2.x 系へ巻き戻すのが安全だ。WP Rollback などのプラグインを使うか、FTP で該当プラグインのフォルダを旧バージョンに差し替える。ただし、旧バージョンには以降のセキュリティ修正が含まれない点には注意が要る。

手動公開に切り替えて一時運用する

致命的エラーは予約投稿の実行時に発生するため、更新が終わるまで予約投稿を避け、公開したいタイミングで管理画面から手動で公開する運用も現実的な選択だ。下書きのまま用意しておき、公開直前に「公開」ボタンを押す流れにすると、サイト運営を止めずに済む。

ステージング環境で先に検証する

本番サイトへの更新が不安な場合は、ステージング環境(本番と同構成の検証用サイト)で先に 3.1.4 を適用し、予約投稿のテストを行う。これにより、他プラグインとの競合や認証トークンの再連携が必要かどうかを事前に確認できる。

デバッグログで原因を特定する手順

デバッグログで原因を特定する手順

プラグインのログ画面に何も残らない場合、PHP のデバッグログを有効にすると致命的エラーの内容が確認できる。本番サイトでは通常エラー表示が無効化されているため、管理画面にも何も出ない。

wp-config.php に次の記述を追加すると、エラー内容が wp-content/debug.log に書き込まれる。あらかじめ FTP または管理画面のテーマファイルエディタから wp-config.php を開いておく。

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

設定後にテスト用の予約投稿を実行し、wp-content/debug.log を確認する。未定義メソッドの場合、「Call to undefined method」(未定義メソッドの呼び出し)という趣旨のエラーが残る。日本語環境でも PHP の内部エラーは英語で記録される。確認後は、WP_DEBUG を false に戻してログ出力を止める。

よくある質問

3.1.4に更新しても予約投稿が失敗する場合は?

まずバージョン表記を確認し、本当に 3.1.4 以上へ置き換わったかを確かめる。そのうえでキャッシュを全削除し、Hootsuite との認証を一度解除して再接続する。それでも改善しない場合は、他プラグインとの競合を切り分ける。

更新ボタンが出てこない場合は?

プロ版や一括購入版では、管理画面の自動更新が効かないことがある。WPZinc の配布ページから最新版をダウンロードし、FTP で該当フォルダを上書きする。上書き前には必ずバックアップを取る。

WP-Cronが正しく動いているか確認するには?

WP Crontrol などのプラグインで予約イベントの一覧を確認し、投稿公開のイベントが登録されているかをチェックする。WP-Cron 自体が停止している場合は、サーバー側の cron 設定や wp-config.php の ALTERNATE_WP_CRON 設定を見直す必要がある。

デバッグログが出力されない場合は?

wp-content フォルダの書き込み権限が不足している可能性がある。FTP で wp-content のパーミッションを確認し、debug.log が作成できる状態か確かめる。あわせて、キャッシュ系プラグインやセキュリティプラグインが wp-config.php の変更をブロックしていないかも確認する。

2.xへ戻してもいいか?

一時的な回避として 2.x 系へ戻すのは有効だが、セキュリティ更新が含まれないため恒久対応にはならない。できるだけ早期に 3.1.4 以降へ更新し、検証のうえで運用を戻すのが望ましい。

この記事のポイント

  • 3.x 更新後に予約投稿が止まる原因は、呼び出しだけ存在する未定義メソッドによる致命的エラー
  • プラグインのログが空でも、PHP のデバッグログを有効にすれば原因が見える
  • 更新版 3.1.4 以降では Cron クラスのメソッド定義が揃い、予約投稿が正常に動く
  • すぐ更新できない場合は 2.x へ巻き戻すか、手動公開で一時運用する
  • 更新前のバックアップと、ステージング環境での事前検証が再発防止につながる
WooCommerce 11.2のライフサイクルフック変更。保存と並び替えでSQL最大45%削減

WooCommerce 11.2のライフサイクルフック変更。保存と並び替えでSQL最大45%削減

WooCommerce 11.1と11.2で、商品保存と商品並び替えの内部処理が大きく変わった。商品保存時のSQLクエリ数は最大45%削減され、並び替えアルゴリズムは大規模カタログ向けに再設計された。

プラグインやカスタムコードで商品データを操作している場合、レガシーフックの移行が必要になる。本記事では変更の全体像、技術的な詳細、そして移行の具体的な手順を解説する。

WooCommerce 11.1と11.2の変更点を俯瞰する

WooCommerce 11.1と11.2の変更点を俯瞰する
今回の変更点の全体像
変更1 商品保存処理の最適化
不要なAPI呼び出しをスキップしてSQL数を最大45%削減
変更2 商品並び替えアルゴリズムの刷新
レガシーフックを非推奨化して範囲ベースの再インデックスに移行
保存処理(キャッシュ無効化の調整)  並び替え処理(アルゴリズムとフック)

2つの変更はいずれも、後方互換性を優先しつつ、大規模な商品カタログでパフォーマンスを改善することを目的としている。

大規模カタログ向けのパフォーマンス改善

WooCommerceチームは、商品数が数千・数万を超えるストアで発生する管理画面の遅延やデータベース負荷を問題視していた。特に商品保存と並び替えは、カタログ全体に影響が及ぶ処理であり、これまでの実装ではカタログが大きくなるほど処理時間が線形に悪化する構造だった。

今回の変更は、商品データストアが不要な書き込みを行わないようにし、並び替えでは全カタログの再インデックスを避ける設計へと置き換えるものだ。これにより、大規模ストアの管理画面レスポンスが大幅に改善される見込みである。

後方互換性の優先とレガシーフックの扱い

重要なのは、非推奨になったフックを使い続けた場合、自動的に旧アルゴリズムへフォールバックする点だ。互換性は保たれるが、その分パフォーマンス改善の恩恵は受けられない。

プラグイン開発者にとっては、古いフックへの依存を解消し、新しいフックへ移行するかどうかの判断が必要になる。次のセクションから、各変更の詳細を見ていく。

商品保存処理の最適化でSQL数を45%削減

商品保存処理の最適化でSQL数を45%削減
従来の商品保存処理(Before)
商品を保存するたびに、値が変わっていなくても以下の処理を実行していた。
ターム関連APIの呼び出し(毎回)
メタデータ削除APIの呼び出し(毎回)
SQLクエリ数が多い
最適化後の商品保存処理(After)
保存前の値と比較して、同じ値ならAPI呼び出しをスキップする。
ターム関連APIの呼び出し(変更時のみ)
メタデータ削除APIの呼び出し(変更時のみ)
SQLクエリ数が最大45%削減

商品保存時の動作が変わり、値に変更がない場合はAPI呼び出しをスキップする。この最適化により、保存1回あたりのSQLクエリ数が最大45%削減される。

no-op書き込みの削減がもたらす効果

今回の最適化は、wp_set_object_terms()delete_post_meta() というWordPressの関数に着目したものだ。これらの関数は、データが変わっていない場合でも呼び出されるとキャッシュを無効化する動作をしていた。いわば「変更がないのに掃除をする」ような無駄が毎回発生していた。

WooCommerce 11.1以降では、保存前の値と保存後の値を比較し、同じ値であればこれらのAPIを呼び出さない。この小さな変更が、商品保存を頻繁に行う大規模ストアでは大きなDB負荷の削減につながる。

フック発火頻度の変化による副作用

ただし注意点がある。set_object_terms フックは、これまで商品保存のたびに発火していた。最適化後は、値が変わった場合のみ発火するようになる。このフックに依存して何らかの処理を実行しているカスタムコードがある場合、想定よりも発火回数が減る可能性がある。

具体的には、商品タイプが変わっていなくても毎回の保存で処理を行うことを前提としたコールバックは、移行が必要だ。次のセクションで確認手順を詳しく解説する。

商品並び替えアルゴリズムの刷新とフック移行

商品並び替えアルゴリズムの刷新とフック移行
商品並び替えフックの移行マップ
非推奨 woocommerce_after_single_product_ordering
カタログ再インデックス中に商品ごとに発火していた
新フック woocommerce_product_ordering_process_reindexed_products
フルカタログ再インデックス後に発火
非推奨 woocommerce_after_product_ordering
並び替え完了後に一度だけ発火していた
新フック woocommerce_product_ordering_process_moved_products
商品が再配置された後に発火
非推奨フック(旧アルゴリズムへフォールバック)  新フック(高速パス)  clean_post_cacheは変更なし

並び替えに関わるフックは2つが非推奨になり、2つの新しいフックが追加された。非推奨フックを使うと旧アルゴリズムにフォールバックする。

旧アルゴリズムから新アルゴリズムへ

従来の商品並び替えは、管理画面の「商品 → すべての商品 → 並び替え」で操作するたびに、カタログ全体を再インデックスしていた。商品数が1万件を超えると、この処理は数十秒かかることもあり、実用に耐えないケースがあった。

新しいアルゴリズムは、大規模カタログを前提に設計されている。再インデックスを高速化し、範囲ベースの並び替えを採用することで、変更された範囲だけを効率的に処理する。これにより、大規模ストアでも並び替え操作が快適になる。

非推奨フックと新フックの対応表

以下の表が、今回変更されたフックの全体像だ。非推奨になったフックを今も使っている場合、対応する新しいフックへの移行を検討する必要がある。

  • woocommerce_after_single_product_ordering は非推奨。カタログ再インデックス中に商品ごとに発火していた
  • woocommerce_after_product_ordering は非推奨。並び替え完了後に一度だけ発火していた
  • clean_post_cache は変更なし。レガシーと高速パスの両方で影響を受けた商品ごとに発火する
  • woocommerce_product_ordering_process_reindexed_products は新設。フルカタログ再インデックス後に発火する
  • woocommerce_product_ordering_process_moved_products は新設。商品が再配置された後に発火する

元の動作を再現するには、clean_post_cachewp_ajax_woocommerce_product_orderingwoocommerce_product_ordering_process_reindexed_productswoocommerce_product_ordering_process_moved_products をプリミティブとして組み合わせる方法が公式に案内されている。

既存サイトが受ける影響と確認手順

既存サイトが受ける影響と確認手順
AIツールを使った確認手順
STEP 1 アクティブなプラグインとテーマの functions.php を対象に検索
STEP 2 add_action(‘set_object_terms’, …) のコールバックを探す
STEP 3 商品タイプが変わっていなくても毎回発火する前提かチェック
STEP 4 該当する場合は woocommerce_update_product や save_post_product への移行を検討

公式ブログでは、AIツールを使ってカスタムコードを確認する方法が提示されている。上の手順で、フックへの依存を洗い出せる。

カスタムコードの確認方法

まず、アクティブなプラグイン、MUプラグイン、テーマの functions.php を対象に、add_action('set_object_terms', ...) というコールバックを検索する。該当があれば、そのコールバックが「商品タイプが変わっていなくても毎回発火すること」を前提にしていないかを確認する。

もし前提にしていた場合、そのコールバックは woocommerce_update_productsave_post_product など、より適切なフックへ移動する必要がある。

移行が必要なケースと不要なケース

移行が必要なのは、set_object_terms フックが毎回発火することを前提にしたコードが存在する場合だ。逆に、商品タイプの変更やカテゴリの変更など、実際に値が変わる場合のみ処理を行いたいというコードは、そのままでも問題ない。

並び替え関連では、woocommerce_after_single_product_orderingwoocommerce_after_product_ordering を使っているコードは、新しいフックへの移行を検討する。非推奨フックを使い続けても動作はするが、旧アルゴリズムにフォールバックするため、パフォーマンス改善の効果を得られない。

この記事のポイント

  • 商品保存処理は、値が変わらない場合はAPI呼び出しをスキップしてSQL数を最大45%削減する
  • 商品並び替えは、全カタログ再インデックスから範囲ベースの新アルゴリズムへ刷新された
  • set_object_terms フックの発火頻度が変わるため、毎回発火を前提としたコードは移行が必要
  • 並び替えの旧フック2つは非推奨になり、新フック2つが追加された
  • 非推奨フックを使い続けると旧アルゴリズムにフォールバックし、高速化の恩恵を受けられない
WordPress 7.1でサイトエディターが真っ白になる原因と直し方

WordPress 7.1でサイトエディターが真っ白になる原因と直し方

WordPress 7.1に更新した後、サイトエディター(wp-admin/site-editor.php)だけが真っ白になる場合は、ブラウザの互換性とJavaScriptエラーを最初に確認し、それでも解決しなければサーバーエラーログとREST APIの応答を調べる。サイトエディターは投稿編集画面と比べてJavaScriptとREST APIへの依存度が高く、原因はこの2系統に集中している。

なぜサイトエディターだけが真っ白になるのか

なぜサイトエディターだけが真っ白になるのか

サイトエディターは、テンプレートやテンプレートパーツ、グローバルスタイルと呼ばれるデザイン設定を、REST API経由でサーバーから取得してJavaScriptで描画する。投稿編集画面が正常でも、サイトエディターだけが真っ白になるのは、この特殊な描画経路のどこかでエラーが起きているためだ。

主な原因は次の4つに分けられる。

  • 古いブラウザが最新JavaScript機能に対応していない
  • JavaScriptファイルの読み込み失敗や例外が起きている
  • REST APIが内部エラーを返してテンプレート情報を取得できない
  • PHPのメモリ不足で致命的エラーが発生している
STEP 1 別のブラウザと端末で開いて確認する
STEP 2 デベロッパーツールでJavaScriptエラーを確認する
STEP 3 サーバーエラーログを直後の時刻で確認する
STEP 4 REST APIの応答を直接チェックする

真っ白な画面の原因切り分けは、この4ステップの順で行うと効率的だ。

古いブラウザが原因かどうかを確認する手順

古いブラウザが原因かどうかを確認する手順

最初に確認するのはブラウザの互換性だ。サイトエディターはブロックエディターと同じく、最新のJavaScript機能をフルに使って動作する。Firefox ESRや数世代前のSafari、旧バージョンのChromeでは、これらの機能に対応できずに画面全体が真っ白になることがある。特に長期的にブラウザをアップデートしていない業務用端末や古いノートPCで起こりやすい。

確認方法はシンプルで、同じサイトを別の端末や別のブラウザで開いてみる。もし最新版のChrome、Edge、Firefoxのいずれかで正常に表示されるなら、使用中のブラウザが古いことが原因だ。その場合はブラウザのアップデートを行うか、対応ブラウザに切り替える。どうしても古いブラウザで作業しなければならない場合は、サイトエディターの使用を避け、投稿編集画面から個別のテンプレートを編集するという回避策もある。

デベロッパーツールでJavaScriptエラーを確認する

デベロッパーツールでJavaScriptエラーを確認する

最新ブラウザでも真っ白になる場合は、デベロッパーツール(開発者ツール)を開いてJavaScriptエラーを調べる。画面が真っ白になる症状の多くは、レンダリングを途中で止めるJavaScriptの例外や、重要なファイルの読み込み失敗が直接の原因になっている。

ChromeやEdgeではF12キー、MacではCommand+Option+Iキーでデベロッパーツールが開く。Firefoxでは右クリックから「要素を調査」を選ぶとよい。開いたら「コンソール」タブに切り替え、ページを再読み込みする。コンソールに赤い文字で表示されるエラーを上から順に確認する。

TypeErrorやReferenceError、SyntaxErrorの表示があれば、それが画面描画を止めている例外だ。また「Failed to load resource」のようなエラーは、必要なJavaScriptファイルが読み込めていないことを示す。この場合は更新時にファイルが欠損した可能性が高いため、後述するWordPress本体の再インストールで解決することが多い。

サーバーエラーログとREST APIを確認する

サーバーエラーログとREST APIを確認する

ブラウザ側に明確なJavaScriptエラーが見つからない場合、次にサーバー側の状態を確認する。サイトエディターはREST API経由でテンプレート情報を取得するため、サーバーでエラーが発生していても画面上には何も表示されず、真っ白なままになる。

サーバーのエラーログを確認するときは、サイトエディターを開いた直後の時刻に注目する。エラーログには過去のボットスキャンや他のリクエストも大量に記録されている。AH01276のようなDirectoryIndex関連のエラーは、多くの場合ボットがディレクトリを直接スキャンした痕跡であり、エディターの真っ白とは無関係だ。ログを上から眺めるのではなく、症状が起きた時刻に新しいエントリが追加されたかどうかを確認する。

サーバーログと並行して、REST APIが正しく応答するかを直接チェックする。ブラウザのアドレスバーに自分のサイトURLに続けて wp-json/wp/v2/templates と入力して開いてみる。正常ならテンプレート一覧の入ったJSONデータが表示される。ここでエラーページやHTTP 500系のエラーが返るなら、REST API側に問題がある。

PHPメモリ上限と再インストールで直す

PHPメモリ上限と再インストールで直す

確認した内容に応じて対処する。PHPのメモリ不足を示すエラー(Allowed memory size of から始まるFatal error)がログに記録されている場合は、メモリ上限を引き上げる。デフォルトの128Mでは、テンプレートの多いサイトや高機能テーマでサイトエディターの読み込み中に不足することがある。wp-config.phpに次の1行を追加するか、レンタルサーバーの管理画面からメモリ上限を変更する。

define('WP_MEMORY_LIMIT', '256M');

エラーログにメモリ不足が出ていない場合や、ブラウザのコンソールにファイル読み込みエラーが出ている場合は、WordPress本体の再インストールが有効だ。ダッシュボードの「更新」メニューを開き、「WordPressを再インストールする」ボタンを押す。wp-admin、wp-includes、ルートのコアファイルが最新版で上書きされ、更新時に欠損したファイルが復元される。テーマやプラグイン、投稿データには影響しない。

再インストール後も症状が続く場合は、一度標準テーマ(Twenty Twenty-Fiveなど)に切り替えてサイトエディターが開くか確認する。標準テーマで開くなら使用中のテーマ側に原因があり、標準テーマでも開かないならサーバー設定やREST APIの応答に原因が残っている可能性が高い。

よくある質問

プラグインをすべて無効化しても直らないのはなぜか

サイトエディターの真っ白はプラグインの競合だけでなく、ブラウザ、JavaScript、REST API、PHPメモリなど複数の要因が絡む。特にREST API経由のデータ取得に失敗している場合はプラグイン無効化だけでは切り分けが不十分だ。ブラウザのコンソールとサーバーログの両方を確認する必要がある。

同じブラウザなのにサイトによって動作が違うのはなぜか

サイトごとに使用中のテンプレートやブロック、グローバルスタイルの構成が異なる。古いブラウザが対応していないJavaScript機能を使うブロックや設定が含まれているサイトだけが真っ白になる。また、サイトごとのメモリ上限やサーバー設定の違いも影響する。

WordPress 7.0に戻した方がよいか

セキュリティ修正を含む更新を戻すのは推奨しない。WordPress 7.1のまま原因を特定して解決する方が安全だ。原因を切り分ける手順を踏めば、ロールバックせずに直せるケースがほとんど。

デベロッパーツールが使えない端末ではどうすればいいか

別の端末やブラウザで同じサイトを開いて症状を再現し、そこからデベロッパーツールやサーバーログを確認する。どうしても別端末が用意できない場合は、サーバーエラーログを症状発生直後の時刻で確認し、PHPの致命的エラーやREST APIの応答を調べるとよい。

この記事のポイント

  • サイトエディターの真っ白はブラウザ互換性を最初に疑う
  • デベロッパーツールでJavaScriptエラーを特定する
  • サーバーエラーログは症状が起きた直後の時刻で確認する
  • REST APIの応答を直接チェックして切り分ける
  • PHPメモリ不足なら上限を引き上げる
  • ファイル欠損が疑わしい場合はWordPress本体を再インストールする