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

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

問題点と目標

問題点

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

※ページ表示速度:PageSpeed InsightsGTmetrixの数値

目標

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

結果

ほぼ満点の結果です。予想以上の効果に驚いてます。(あとは、表示速度向上によってGoogle検索で上位表示されれば言うことなしです)

改善前

PageSpeed Insights1

GTmetrix1

改善後

PageSpeed Insights2

GTmetrix2

やったこと

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

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

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

やったこと(まとめ)

  • HTML解析段階でAdSenseを読込まない
    • adsbygoogle.jsを読込むscriptタグを記述しない
  • 初回のユーザイベントで初めてAdSenseの読込みを開始する
    • スクロール/マウス移動/マウス押下/タッチ開始
  • ただし、読込み時にスクロール済みの場合、遅延読込みをしない(※1)
    • できるだけ、早くAdSenseを読込むための例外
    • 「既に読んでいる途中に更新した時」「ページ内リンクの時」
  • ただし、scrollイベントが発生しない場合は、遅延読込みをしない(※1)
    • ドキュメント全体の領域と表示領域が等しい時
    • 保険としての例外的なコードです

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

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

  • loadイベント時にAdSenseを読込む
    • 非同期読込みとほぼ同じ、ページ表示速度だった
  • loadイベント時にsetTimeoutでAdSenseを読込む
    • setTimeoutの遅延分遅くなる(読込み開始が遅れる分更に遅くなっているはず)
  • clickイベントをJavaScriptで人工的に発生させて、下記のコードで無理やり読み込む
    • JavaScriptで人工的に呼び出したクリックイベントでは読込みは始まらなかった
  • scrollイベントをJavaScriptで人工的に発生させて、下記のコードで無理やり読み込む
    • PageSpeed Insightsでは、高得点となった
    • GTmetrixでは、低得点となった
    • 強制的スクロールは、ユーザが目視で違和感を感じるため、やめておいたほうが無難?

導入手順

  1. <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>をHTML上からすべて削除する
    • 1つでも残っていると効果がありません
  2. 下記のコードを</body>直前に配置する

コード

(function() {
  function main() {
    // GoogleAdSense読込み
    var ad = document.createElement('script');
    ad.type = 'text/javascript';
    ad.async = true;
    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;
      document.removeEventListener('scroll', onLazyLoad);
      document.removeEventListener('mousemove', onLazyLoad);
      document.removeEventListener('mousedown', onLazyLoad);
      document.removeEventListener('touchstart', onLazyLoad);

      main();
    }
  }
  document.addEventListener('scroll', onLazyLoad);
  document.addEventListener('mousemove', onLazyLoad);
  document.addEventListener('mousedown', onLazyLoad);
  document.addEventListener('touchstart', onLazyLoad);
  document.addEventListener('load', function() {
    // ドキュメント全体が表示領域の内側 or ドキュメント途中(更新時 or ページ内リンク)
    if (document.body.clientHeight == document.documentElement.clientHeight
        || document.documentElement.scrollTop != 0
        || document.body.scrollTop != 0) {
      onLazyLoad();
    }
  });
})();

補足

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

参考

関連記事

コメント: 2

匿名 さんのコメント...

firefoxで見ると、adsense広告は表示されませんね。。。

toshi さんのコメント...

ご指摘ありがとうございます。
当記事の内容を適用したページ(本ページ)をFirefox66(現在最新版)で表示してAdsense広告が表示されることを確認しました。

ご指摘の環境で広告ブロッキングをしたり、JavaScriptが無効になっていませんでしょうか?

ちなみに、Firefoxのコンテンツブロッキングを有効にしている場合、GoogleAdsenseは表示されません。(仕様です)

コメントを書く