はじめに
「WordPress高速化」シリーズの第4回です。【WordPress高速化】YouTube埋め込みを遅延読み込み(以下「前回の記事」)では、Intersection Observerを使って、YouTubeの動画を画面に近づいたときだけ読み込むようにしました。
今回は、同じ仕組みをGoogle AdSenseの広告に使います。記事の一番下にある広告は、読者の多くが見ないままページを離れます。それなのに、ページを開いた時点で広告の読み込みが始まっています。これを、広告枠ごとに、画面に近づいたときだけ読み込むように変えます。
ただし、広告のコードを変えるので、先にAdSenseのポリシーを確認します。また、単純に遅らせると別の枠に広告が入ってしまう落とし穴があったので、その避け方も紹介します。
Intersection Observerの基本の書き方は、前回の記事で解説しています。この記事のコードは、子テーマの functions.php と JavaScript のファイルを使います。編集する前に、必ずバックアップを取ってください。
AdSenseのポリシーは大丈夫?
結論から書くと、AdSenseの公式ヘルプには、広告の遅延読み込みについての明確な記述はありません(2026年10月時点)。許可するとも、禁止するとも書かれていません。
公式ヘルプのAdSense 広告コードの修正では、「広告の掲載結果を作為的に高めたり、広告主に損害を与えたりしない限り、広告コードは変更してよい」とされています。禁止されている変更の例は次のとおりです。
display:noneなどで広告ユニットを隠す(レスポンシブ広告は除く)- 広告とコンテンツが重なるように配置する
- 隠したキーワードなどで、表示される広告の内容を操作する
- 画面にスライドイン、ズームなどで、不当に注目を集める
- スマホで画面をドラッグしたときに、広告がクリックされるようにする
一方、Googleの広告配信サービス(Google アド マネージャー)のヘルプ視認性を高めるおすすめの方法では、広告枠の近くまでスクロールしたときに広告を配信する遅延読み込みが、読み込み時間の短縮や視認性の向上につながる方法として紹介されています。
そこで、この記事では次のルールを守ります。
| ルール | 理由 |
|---|---|
| 変えるのは「いつ読み込むか」だけ | 広告の中身・サイズ・動きは変えない |
| 広告枠を隠さない | display:none などで隠すのは禁止されている |
| 表示の演出を付けない | スライドインなどの「不当に注目を集める表示」を避ける |
| 1つの枠につき、読み込みは1回だけ | 表示されない広告の要求を何度も送らない |
| 対象は、スクロールしないと見えない枠だけ | 最初の画面の近くにある広告は、今までどおり読み込む |
遅延読み込みにすると、読者が広告の近くまでスクロールしなかった場合、その広告は表示されません。そのため、表示回数や収益が減ることがあります。ページの速さと収益のどちらを優先するかを考えたうえで、対象の枠を選んでください。ポリシーに不安がある場合は、AdSenseのヘルプやコミュニティで確認してから導入しましょう。
今の状態を確かめる
SWELLのウィジェットなどに貼るAdSenseの広告コードは、次のような形です。
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="1234567890"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script><ins class="adsbygoogle">:広告を表示する枠(adsbygoogle = window.adsbygoogle || []).push({});:「この枠に広告を入れて」という依頼
当サイトでは、SWELLの「スクリプトの遅延読み込み」で、AdSense本体のファイル(adsbygoogle.js)を後から読み込んでいます。この機能は、読者が操作したとき、または数秒たったときに、ページ内のすべての枠の広告をまとめて読み込みます。記事の一番下の広告も、読者がそこまで読むかどうかに関係なく、読み込まれます。
今回の方法は、この依頼(push)を、枠が画面に近づくまで出さないようにするものです。SWELLの機能と組み合わせて使えます。
対象の枠を決める
当サイトの記事ページ(第3回)で、広告枠がページの上から何pxの位置にあるかを測りました(パソコン、画面の高さ900px)。
| 広告枠 | 位置 | 遅延読み込み |
|---|---|---|
目次の下(.w-beforeToc) | 1,175px | しない |
サイドバー1つ目(#swell_ad_widget-3) | 1,179px | しない |
サイドバー2つ目(#swell_ad_widget-2) | 2,008px | する |
記事の下(#swell_ad_widget-9) | 12,315px | する |

最初の画面のすぐ下にある枠は、ほとんどの読者が見るので、今までどおり読み込みます。目安は、画面の高さの1.5倍くらいまでです。記事の下の広告は、12,000px以上も下にあるので、遅延読み込みの効果が一番大きい枠です。
位置は、前回までと同じように検証ツールで確認できます。広告枠を右クリック→「検証」で選び、コンソールで次のように入力すると、ページの上からの位置がわかります。
// 選んでいる要素の、ページの上からの位置(px)
Math.round($0.getBoundingClientRect().top + scrollY)落とし穴:push({})は「上にある、まだ空の枠」を埋める
最初に思いつくのは、「広告コードの push の行を外して、枠が画面に入ったら push({}) する」という方法です。しかし、これには落とし穴があります。
push({}) は、どの枠に広告を入れるかを指定しません。ページの中で、class="adsbygoogle" が付いていて、まだ広告が入っていない枠のうち、HTMLで一番先にある枠を埋めます。
SWELLのレイアウトでは、HTMLの順番は「本文(記事の下の広告を含む)→ サイドバー」です。ところが画面の上では、サイドバーの広告のほうが、記事の下の広告よりずっと上に見えます。

テスト用のページで確かめると、実際に次のようになりました(広告が入った枠は、AdSenseが data-adsbygoogle-status="done" という印を付けるので、それで判断しています)。
| 書き方 | サイドバーの枠までスクロール | 記事の下までスクロール |
|---|---|---|
画面に入ったら push({}) するだけ | 記事の下の枠に広告が入り、サイドバーは空のまま | ここでやっとサイドバーに入る |
| この記事の方法(class を切り替える) | サイドバーの枠だけに入る | 記事の下の枠に入る |
これを避けるため、遅延させる枠には、最初は adsbygoogle とは別の class を付けておきます。画面に近づいたときに class を adsbygoogle に戻してから push({}) すれば、空の枠の候補には、その枠しかありません。
AdSenseを枠ごとに遅延読み込みする方法
Step1:広告コードの class を変え、push の行を外す
SWELLの「外観」→「ウィジェット」で、遅延読み込みしたい広告のウィジェットを開き、広告コードを次のように書き換えます。
<ins class="lazy-adsbygoogle"
style="display:block"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="1234567890"
data-ad-format="auto"
data-full-width-responsive="true"></ins>class="adsbygoogle"をclass="lazy-adsbygoogle"に変える<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>の行を消すdata-ad-clientやdata-ad-slotなどは、元のままにする

Step2:functions.phpでJavaScriptを読み込む
子テーマの functions.php に、次のコードを追加します。サイドバーの広告はどのページにもあるので、ページの種類は限定しません。
// 広告枠ごとの遅延読み込み用のJavaScriptを読み込む
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'ad-lazy',
get_stylesheet_directory_uri() . '/js/ad-lazy.js',
[],
'1.0',
['in_footer' => true, 'strategy' => 'defer']
);
});Step3:画面に近づいたら、class を戻して広告を読み込む
子テーマの js フォルダに、ad-lazy.js というファイルを作ります(wp-content/themes/swell_child/js/ad-lazy.js)。
// class="lazy-adsbygoogle" の広告枠が画面に近づいたら、class を戻して広告を読み込む
document.addEventListener('DOMContentLoaded', () => {
const slots = document.querySelectorAll('ins.lazy-adsbygoogle');
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
const ins = entry.target;
obs.unobserve(ins);
ins.classList.replace('lazy-adsbygoogle', 'adsbygoogle');
(window.adsbygoogle = window.adsbygoogle || []).push({});
});
}, { rootMargin: '300px 0px' });
slots.forEach((ins) => observer.observe(ins));
});unobserveで見張りをやめてから読み込むので、1つの枠につきpushは1回だけですclassList.replaceで class をadsbygoogleに戻してからpush({})するので、その枠に広告が入りますrootMarginは、前回の動画(200px)より少し大きい300pxにしました。広告は表示までに時間がかかるので、早めに依頼を出します
AdSense本体のファイルがまだ読み込まれていない(SWELLの遅延の待ち時間中の)ときは、依頼は adsbygoogle という配列にたまり、本体が読み込まれた時点で処理されます。そのため、SWELLの「スクリプトの遅延読み込み」は今のままで大丈夫です。ただし、ad-lazy.js 自体は、SWELLの遅延の対象に入れないでください。
Step4:検証ツールで確認する
- 記事を開き、F12で検証ツールを開く
- 「要素」パネルで
lazy-adsbygoogleを検索する(Ctrl+F) - ページを開いた直後は、class が
lazy-adsbygoogleのままで、広告は入っていない - その枠までスクロールすると、class が
adsbygoogleに変わり、data-adsbygoogle-status="done"が付く
↓ 記事を開いた直後に確認した検証ツール「要素」の状況画像がこちらです。↓

↓ 広告枠直前までスクロールを進めていったあとの検証ツール「要素」の状況画像がこちらです。↓

記事の下広告枠のclassがadsbygoogleに変わり、data-adsbygoogle-status=”done”が付いています。
PHPで広告コードを自動で書き換える方法
Step1では、ウィジェットの広告コードを手で書き換えました。この書き換えは、PHPで自動にすることもできます。ウィジェットに貼った広告コードは元のままで済み、コードを外せばすぐ元の動きに戻せます。
この方法は、Step1の代わりに使います。Step2〜4は、そのまま必要です。
対象のウィジェットのIDを調べる
記事を開いて検証ツールの「要素」パネルで広告枠を選び、外側の要素の id を確認します。SWELLの「広告タグ」ウィジェットは、id="swell_ad_widget-9" のようなIDになっています。当サイトでは、サイドバー2つ目が swell_ad_widget-2、記事の下が swell_ad_widget-9 でした。
functions.phpにコードを追加する
子テーマの functions.php に、次のコードを追加します。$lazy_ids には、調べたIDを書きます。
// 指定した広告ウィジェットのコードを、遅延読み込み用に自動で書き換える
add_filter('widget_display_callback', function ($instance, $widget, $args) {
// 遅延読み込みにする広告ウィジェットのID
$lazy_ids = ['swell_ad_widget-2', 'swell_ad_widget-9'];
if (is_admin() || !in_array($widget->id, $lazy_ids, true) || empty($instance['code'])) {
return $instance;
}
// 枠の class を変える
$instance['code'] = str_replace('class="adsbygoogle"', 'class="lazy-adsbygoogle"', $instance['code']);
// 広告を依頼する script を消す
$instance['code'] = preg_replace(
'/<script>\s*\(adsbygoogle\s*=\s*window\.adsbygoogle\s*\|\|\s*\[\]\)\.push\(\{\}\);\s*<\/script>/',
'',
$instance['code']
);
return $instance;
}, 10, 3);widget_display_callbackフィルター:ウィジェットが表示される直前に、その設定値($instance)を書き換えられます。データベースに保存された広告コードは変わりません$instance['code']:SWELLの「広告タグ」ウィジェットに貼った広告コードですstr_replace:枠の class をlazy-adsbygoogleに変えます(Step1の1つ目と同じ)preg_replace:push({})の<script>を消します(Step1の2つ目と同じ)。改行や空白が入った書き方にも対応しています$lazy_idsに書いていないウィジェットは、何も変わりません
テスト用の環境(Local)で、本番と同じ1行の広告コードと、AdSenseの管理画面からコピーした複数行の広告コードの両方を試しました。どちらも、指定した2つの枠だけ class が変わって push が消え、ほかの枠と、AdSense本体を読み込む <script async src="…adsbygoogle.js"> はそのまま残りました。SWELLの「スクリプトの遅延読み込み」がオンでもオフでも、対象の枠は、その枠までスクロールしたときだけ広告が入りました。
ページ全体を書き換えない理由
ページのHTMLを丸ごと受け取って、すべての adsbygoogle を書き換える方法も考えられます。しかし、次の理由でおすすめしません。
- 目次の下などの広告まで遅延になる:HTMLの文字列からは、枠が画面のどこに表示されるかが分かりません
- SWELLの機能とぶつかる:SWELLの「スクリプトの遅延読み込み」も、ページ全体の
<script>を書き換えています。処理の順番によっては、pushの<script>が別の形に変わっていて、消せなくなります - 本文の中の広告も書き換わる:記事の本文に直接貼った広告コードまで対象になります
ウィジェットごとに書き換えれば、対象の枠を確実に選べます。ウィジェットは出力される前に書き換わり、SWELLがページ全体を書き換えるのはその後なので、ぶつかりません。
このコードは、SWELLの「広告タグ」ウィジェットに貼った広告コードが対象です。ブロックウィジェットの「カスタムHTML」に貼った広告や、カスタマイザーで設定する目次の下の広告は、書き換わりません。また、class='adsbygoogle'(シングルクォート)のように書き方が違う広告コードは、置き換えの文字列と一致しないので、Step4の方法で書き換わったか必ず確認してください。
注意点
- 第2回で確保した高さは、そのまま残します:枠の高さは
min-heightで先に確保しているので、広告があとから入ってもページはずれません(詳しくは【WordPress高速化】SWELLのCLSをCSSで改善) - 自動広告には使えません:自動広告は、AdSenseが広告の場所を自分で決めるため、この方法の対象外です。当サイトの自動広告は全画面広告だけなので、そのままにしています
- スマホで非表示の枠は読み込まれません:パソコンだけで表示する設定のサイドバーの広告は、スマホでは画面に入らないため、依頼が出ません
- フェードインなどの演出は付けない:見た目の演出は、ポリシーの「不当に注目を集める表示」に当たるおそれがあるので、付けていません
よくある質問・エラー対処
Q. コンソールに「All ‘ins’ elements in the DOM with class=adsbygoogle already have ads in them」と出ます
→ 空の枠がないのに push({}) が呼ばれたときのエラーです。Step1で、広告コードの push の行を消し忘れていないか確認してください。消し忘れていると、ページを開いたときにほかの枠を埋めてしまい、遅延させた枠の順番がずれます。
Q. 遅延させた枠に、いつまでも広告が表示されません
→ 次の点を確認してください。
- class の書き間違い(
lazy-adsbygoogleのつづり) ad-lazy.jsの場所(swell_child/js/ad-lazy.js)と、「ネットワーク」タブで読み込まれているか- キャッシュ系のプラグインやSWELLのキャッシュを削除したか
また、広告の在庫がないときは、遅延読み込みとは関係なく、枠が空のままになることがあります(data-ad-status="unfilled")。
Q. 目次の下の広告も遅延させたほうが速くなりますか
→ 最初の画面の近くにある枠は、ほとんどの読者がすぐに見るので、遅延させても読み込む量はあまり変わりません。表示が遅れるぶん、読者が広告を見る前に通り過ぎることもあります。当サイトでは、目次の下とサイドバー1つ目の広告は対象にしていません。
おわりに(まとめ)
AdSenseの広告も、Intersection Observerで枠ごとに、画面に近づいたときだけ読み込めます。
- ✅ AdSenseの公式ヘルプには、遅延読み込みの明確な記述はない(2026年10月時点)
- ✅ 変えるのは読み込むタイミングだけ。枠を隠さない、演出を付けない、1枠1回
- ✅ 対象は、スクロールしないと見えない枠だけ
- ✅ push({}) は「HTMLで先にある、まだ空の枠」を埋めるので、単純に遅らせると別の枠に入る
- ✅ 遅延させる枠は class を lazy-adsbygoogle にしておき、画面に近づいたら戻して push する
- ✅ widget_display_callback を使えば、指定したウィジェットの広告コードだけを自動で書き換えられる
- ✅ 表示回数や収益が減ることもあるので、速さとのバランスで決める
この記事が、少しでも誰かのお役に立てれば幸いです。
関連記事
- 【WordPress高速化】YouTube埋め込みを遅延読み込み:Intersection Observerの基本と、画面外の動画の読み込みを0KBにした方法(シリーズ第3回)
- 【WordPress高速化】SWELLのCLSをCSSで改善:広告枠などに高さを確保して、CLSを0.14から0.0008に下げた実例(シリーズ第2回)
- 【WordPress高速化】CLSの原因を検証ツールで探す方法:検証ツールで、ずれた場所を見つけて高さを測る方法(シリーズ第1回)
※1回買えば複数サイトで使い回しOK
当サイトの記事で使用したVBAなどのサンプルをDLできます
この記事のサンプルはありません!
ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


