トイレのうず

PageSpeed Insights にて Google AdSense を遅延読み込みさせ、モバイルのスコアを 80 から 98 に上げた話です。

サイトのデザインを新しくしてページの読み込み速度を早くするために、画像を遅延読み込みさせたり、スタイルシートやスクリプトの読み込み順を考えたりしてサイトを構築したのですが、 PageSpeed Insights で速度を測ってみると 80 点という結果でした。調べてみると PageSpeed Insights のサーバーがアメリカにありかつ 3G 回線でチェックしているので、 Google AdSense を入れていると、 80 点くらい取れれば御の字のようです。もっとスコアを高くしたいと思いさらに調べていると、 Google AdSense を遅延読み込みすることで PageSpeed Insights の点数が爆発的に上がるようなので試してみました。

アドセンス遅延読み込み前:スコア 80 点

AdSense を遅延読み込みすると 98 点になりました。

アドセンス遅延読み込み後:スコア 98 点

ボトルネックは Google AdSense

施策前の GTmetrix のモバイルのウォーターフォールです。

GTmetrix のウォーターフォールにて adsbygoogle.js が先に読み込まれている

スタイルシートとスクリプトを </body> 直前に置いているので、コンテンツ内にある adsbygoogle.js が style.min.css より先に読み込まれていてレンダリング等を行っているのでページのスピードが全体的に遅くなってしまっています。 </body> 直前で adsbygoogle.js を読み込ませるようにしたりしましたが、 PageSpeed Insights の点数はあまり変わりませんでした。

Google AdSense を遅延読み込み

そこで Google AdSense を遅延読み込みしてみることにしました。コードを参考にしたのは以下のページです。すごくよく考えられているのでそのまま使わせていただきました。

→バグ取りの日々: Google AdSense の遅延読込みでページ表示速度を改善


(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);

スクロールやマウスダウンなどユーザーが操作をしたときに adsbygoogle.js を読み込んで広告を表示しています。 AdSense を貼りつけたときに含まれている以下のスクリプトを読み込む行をすべての広告コードから削除します。


<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

WordPress で </body> 直前に読み込む関数

上のコードを圧縮して WordPress で </body> 直前に出力する関数を作ってみました。


//adsbygoogle.jsの遅延読み込み
function my_register_ads_script(){
	if( is_single() ){
		wp_register_script( 'adsbygoogle-js', false, array(), false, true );
		wp_enqueue_script( 'adsbygoogle-js' );
		//JavaScript参考
		//https://www.bugbugnow.net/2019/05/GoogleAdSense-lazy-loading.html
		$ga_js = <<< EOF
!function(e,t){var n=!1;function o(){!1===n&&(n=!0,t.removeEventListener("scroll",o),t.removeEventListener("mousemove",o),t.removeEventListener("mousedown",o),t.removeEventListener("touchstart",o),function(){var t=e.createElement("script");t.type="text/javascript",t.async=!0,t.src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";var n=e.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}())}t.addEventListener("scroll",o),t.addEventListener("mousemove",o),t.addEventListener("mousedown",o),t.addEventListener("touchstart",o),t.addEventListener("load",function(){0==e.documentElement.scrollTop&&0==e.body.scrollTop||o()})}(document,window);
EOF;
		wp_add_inline_script('adsbygoogle-js', $ga_js, 'after');
	}
}
add_action( 'wp_enqueue_scripts', 'my_register_ads_script', 100 );

wp_register_script() で URL を false にしたものを一度登録して、再度 wp_enqueue_script() することで空のスクリプトが登録されます。これに wp_add_inline_script() でインラインスクリプトをつけ加えると、インラインスクリプトのみ出力されます。また個別投稿ページしか Google AdSense を貼っていないので is_single() で場合別けをしています。

施策後のウォーターフォール

GTmetrix のウォーターフォールにて adsbygoogle.js の読み込みがなくなりリクエストが 17 に減少した

施策後のウォーターフォールでは画面にアクセスしたときは adsbygoogle.js が読み込まれずリクエストが 37 から 17 へ激減してスッキリしています。

再レンダリングを防ぐスタイルシート

この施策だけだと広告の高さがわからないので、初めは高さゼロでレンダリングされ広告が読み込まれたときに高さがわかるので再レンダリングが行われ画面がガタつきます。これを防ぐためにコードを <div> 要素で囲み CSS にて広告スペースを予め確保しておきます。このサイトだと Google AdSense は以下のようなコードになっています。


<aside class="google-ads">
	<h2>スポンサーリンク</h2>
	<div>
		<!-- トイレのうず記事上 -->
		<ins class="adsbygoogle"
		     style="display:block"
		     data-ad-client="ca-pub-XXXXXXXXXXXXXX"
		     data-ad-slot="XXXXXXXXX"
		     data-ad-format="auto"
		     data-full-width-responsive="true"></ins>
		<script>
		     (adsbygoogle = window.adsbygoogle || []).push({});
		</script>
	</div>
</aside>

.google-ads > div{
	margin: 0 auto;
	max-width: 1024px;
	min-height: 268px;
}
@media screen and (min-width:374px) {
	.google-ads > div{
		min-height: 312px;
	}
}
@media screen and (min-width:414px) {
	.google-ads > div{
		min-height: 345px;
	}
}
@media screen and (min-width:768px) {
	.google-ads > div{
		min-height: 90px;
	}
}

広告のサイズをレスポンシブにしているので CSS で高さを決め打ちできないのでメディアクエリで 320px 、 374px 、
414px 、 768px 以上の場合にわけ、モバイルはスクエア、タブレットとデスクトップでは横長タイプの高さを min-height で指定しています。これで広告スペースが確保されているのでスクロールをしたときに、自然に遅延読み込みした広告が表示されます。万が一指定した値より大きい広告が表示されても最小値で指定しているので高さを確保するために再レンダリングが行われので広告が隠れることもありません。

Google AdSense を遅延読み込みさせるだけでこんなに PageSpeed Insights のスコアが上がるとは思いませんでした。体感はそんなに変わらないのでやった意味があるのかわかりませんがなんとなく気分がいいです。そのほかの高速化については以下の本がまとまってわかりやすいです。

関連記事

lazySizes でレスポンシブイメージの遅延読み込み (lazy load) を WordPress に組み込む
WordPress
モバイル85 パソコン94「画像を最適化する」対策後
レスポンシブ対応画像の遅延読み込み時に再レンダリングされるのを防止する方法
WordPress
画像の高さが未指定だと画像遅延読み込みで再レンダリングされる
Google Maps API をいじっています
Web制作
thumbnail
Google Analytics に検索エンジンを追加+外部ファイル化
Web制作
thumbnail
CSS および JS ファイルに Googlebot がアクセスできません
WordPress
CSS および JS ファイルに Googlebot がアクセスできません
WordPress で「スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する」に対応する
WordPress
above the fold(ファーストビュー、スクロールせずに見える領域)

コメントを書く