GoogleAdSenseの遅延読込みでページ表示速度を改善

GoogleAdSenseの読込みの遅さを改善する。

問題点と目標

問題点

GoogleAdSenseは、JavaScript/画像/フォント/設定ファイルなどの複数データを読込むため、非常に低速です。そのため、広告を導入したページは、広告のないページに比べてページ表示速度が低速です。

※ページ表示速度は、PageSpeed InsightsGTmetrixの数値を使用しています

目標

GoogleAdSenseを読込みつつ、ページ表示速度をできる限り早くすることです。

結果

ほぼ満点の結果です。予想以上の効果に正直驚いてます。(あとは、表示速度向上によってGoogle検索で上位表示されれば言うことなしです。まあ、Google先生なら既に加味してるんだろうな…)

改善前

PageSpeed Insights1GTmetrix1

改善後

PageSpeed Insights2GTmetrix2

やったこと

初回のユーザイベントまで読込みを遅延する。これにより、ユーザ操作がなければ、いつまでたってもGoogleAdSense広告を表示しないことになります。

「いつまでも広告を表示しない」のは、悪いことのように思えます。ですが、これによりページ表示速度の計測からGoogleAdSenseの読込みが除外されるため、ページ表示速度が高速化します。これは、早く読み込むことで高速化するのではなく、遅く読込むことによって(ページ表示速度の計算外のタイミングで読み込むため、ページ表示速度が)高速化します。

そして、初回のユーザイベントはスクロールで発生するため、一定量の記事を読めば発生します。記事を読んだユーザに広告を表示できます。

やったこと(まとめ)

  • HTML解析段階でGoogleAdSenseを読込まない
    • adsbygoogle.jsを読込むscriptタグを記述しない
  • 初回のユーザイベントで初めてGoogleAdSenseの読込みを開始する
    • スクロール/マウス移動/マウス押下/タッチ開始
  • ただし、読込み時にスクロール済みの場合、遅延読込みをしない(※1)
    • できるだけ、早くGoogleAdSenseを読込むための例外
    • 例「既に読んでいる途中に更新した時」「ページ内リンクの時」

※ページの折り目より上にGoogleAdSenseを貼ってある場合、ユーザが違和感を感じる可能性があります
 例:スクロールしたら、いきなり画面中央に広告が現れる
※1:loadイベントで遅延読込みしない判定をするため、<head>内で読込む場合と比べると遅くなる

やってみてだめだったこと(失敗談)

  • loadイベント時にGoogleAdSenseを読込む
    • 非同期読込みとほぼ同じページ表示速度だった(高速化しない)
  • loadイベント時にsetTimeoutでGoogleAdSenseを遅延して読込む
    • setTimeoutの遅延分、読込みが遅くなる(読込み開始が遅れる分更に遅くなっている)
    • setIntervalも同様
    • TTI(インタラクティブになるまでの時間)との兼ね合いと思われる
  • clickイベントをJavaScriptで人工的に発生させて、下記のコードで無理やり読込む
    • JavaScriptで人工的に呼び出したクリックイベントでは読込みが始まらなかった
  • scrollイベントをJavaScriptで人工的に発生させて、下記のコードで無理やり読込む
    • 強制的スクロールは、ユーザが目視で違和感を感じるため、やめた方が無難

導入手順

  1. GoogleAdSenseの読み込みコードをHTML上からすべて削除する
    • 新コード例:<script data-ad-client="ca-pub-XXXXXXXXXXXXXXXX" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    • 旧コード例:<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    • 1つでも残っていると効果がない
  2. 下記のサンプルコードを</body>直前に配置する

補足

下記のサンプルコードの場合、初回のユーザイベントのタイミングで発火します。そのため、初回のユーザイベントがloadイベント前に発生した場合、loadイベント前に発火する可能性があります。コンテンツの読み込み完了後(loadイベント以降)に、発火させたい場合、初回ユーザイベントで発火する:onLazy.jsを参照してください。

また、loadイベント後にGoogleAdSenseを読み込む場合、(自動広告などの)一部機能が正常に動作しない可能性があるようです。GoogleAdSenseがloadイベントを使用して処理している場合、loadイベント後に読込んでもイベントの通知が行われずloadイベントが処理されないため、正常に動作しないものと推測されます。環境に悪影響がないか確認してから自己責任で導入してください。

※ちなみに、筆者の環境では、自動広告が正常に表示されました。

サンプルコード

GoogleAdSense遅延読込みサンプルコード(function(window, document) {
  function main() {
    // GoogleAdSense読込み
    var ad = document.createElement('script');
    ad.type = 'text/javascript';
    ad.async = true;
    // 新コードの場合、サイト運営者IDを書き換えてコメントアウトを外す
    // 旧コードの場合、コメントアウトしたままにする
    //ad.dataset.adClient = 'ca-pub-XXXXXXXXXXXXXXXX';
    ad.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
    var sc = document.getElementsByTagName('script')[0];
    sc.parentNode.insertBefore(ad, sc);
  }

  // 遅延読込み
  var lazyLoad = false;
  function onLazyLoad() {
    if (lazyLoad === false) {
      // 複数呼び出し回避 + イベント解除
      lazyLoad = true;
      window.removeEventListener('scroll', onLazyLoad);
      window.removeEventListener('mousemove', onLazyLoad);
      window.removeEventListener('mousedown', onLazyLoad);
      window.removeEventListener('touchstart', onLazyLoad);
      window.removeEventListener('keydown', onLazyLoad);

      main();
    }
  }
  window.addEventListener('scroll', onLazyLoad);
  window.addEventListener('mousemove', onLazyLoad);
  window.addEventListener('mousedown', onLazyLoad);
  window.addEventListener('touchstart', onLazyLoad);
  window.addEventListener('keydown', onLazyLoad);
  window.addEventListener('load', function() {
    // ドキュメント途中(更新時 or ページ内リンク)
    if (window.pageYOffset) {
      onLazyLoad();
    }
  });
})(window, document);

2021年07月19日からの新しい AdSense コード対応

新しいAdSenseコードについては、次のページを参照してください。

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234" crossorigin="anonymous"></script>

上記「GoogleAdSense遅延読込みサンプルコード」のmain関数を下記に置き換えることで2021年07月19日からの新しい AdSense コードに対応できます。(ただし、サイト運営者IDについては、サイト運営者様で個別に対応が必要になります)

...
  function main() {
    // GoogleAdSense読込み
    var ad = document.createElement('script');
    ad.type = 'text/javascript';
    ad.async = true;
    ad.crossorigin = 'anonymous';
                                                                                  /*↓要修正↓*/
    ad.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234';
    var sc = document.getElementsByTagName('script')[0];
    sc.parentNode.insertBefore(ad, sc);
  }
...

※サイト運営者ID(例:ca-pub-1234)をご自身のIDに置き換える必要があります。
※2021年07月19日以降でも、元のコードは今まで通り動作します。

補足

今回は、対象がGoogleAdSenseだっただけで、上記コードで遅延ロードが可能です。初回時に確実にはロードされない欠点を除けば、初回のユーザイベント発生時点で読込みに行くため、それなりの速さでかつ安定的に読込みが完了します。そのため、他にも良い使い道があるのではと考えます。すぐには思いつきませんが…。


Googleアドセンスのメールサポートを受けられる方が問い合わせをしてくださったようです。GoogleAdSenseの遅延読み込みの導入自体は禁止ではないそうです。禁止の可能性もあったんですよね…ある程度は覚悟していましたが、肝が冷える思いです。メールサポートがもらえるようになりたいです…。

技術部門との確認が必要とのことでご回答までに少し時間がかかりました。
回答をそのまま記載するのは問題があるかも知れませんのポイントだけ共有します。

遅延読み込みについてポリシー上、導入禁止ではないが、それによって広告の表示やデザインに影響が発生した場合、広告主の意図しない配信となり違反措置がつく可能性はある。

以上をご留意する必要があります。
個人的にはページ表示速度の向上により若干の波及効果はありそうですが、総合的に考えますと導入メリットはない気がしました。

アドセンスブログで稼ぐ."Googleアドセンス|メールの問い合わせやサポートはどこから?" (最終閲覧日: 2020年02月13日)

※GoogleAdSenseの公式発表データではないのであしからず
 (引用先からの又聞きの情報です)

参考

関連記事