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を読込むための例外
    • 例「既に読んでいる途中に更新した時」「ページ内リンクの時」

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

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

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

導入手順

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

補足

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

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

コード

(function(doc, win) {
  function main() {
    // GoogleAdSense読込み
    var ad = doc.createElement('script');
    ad.type = 'text/javascript';
    ad.async = true;
    ad.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
    var sc = doc.getElementsByTagName('script')[0];
    sc.parentNode.insertBefore(ad, sc);
  }

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

      main();
    }
  }
  win.addEventListener('scroll', onLazyLoad);
  win.addEventListener('mousemove', onLazyLoad);
  win.addEventListener('mousedown', onLazyLoad);
  win.addEventListener('touchstart', onLazyLoad);
  win.addEventListener('load', function() {
    // ドキュメント途中(更新時 or ページ内リンク)
    if (doc.documentElement.scrollTop != 0 || doc.body.scrollTop != 0) {
      onLazyLoad();
    }
  });
})(document, window);

補足

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

参考

関連記事

コメント: 2

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

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

toshi さんのコメント...

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

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

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

コメントを書く