PageSpeed Insights にて Google AdSense を遅延読み込みさせ、モバイルのスコアを 80 から 98 に上げた話です。
サイトのデザインを新しくしてページの読み込み速度を早くするために、画像を遅延読み込みさせたり、スタイルシートやスクリプトの読み込み順を考えたりしてサイトを構築したのですが、 PageSpeed Insights で速度を測ってみると 80 点という結果でした。調べてみると PageSpeed Insights のサーバーがアメリカにありかつ 3G 回線でチェックしているので、 Google AdSense を入れていると、 80 点くらい取れれば御の字のようです。もっとスコアを高くしたいと思いさらに調べていると、 Google AdSense を遅延読み込みすることで PageSpeed Insights の点数が爆発的に上がるようなので試してみました。
AdSense を遅延読み込みすると 98 点になりました。
目次
ボトルネックは Google AdSense
施策前の GTmetrix のモバイルのウォーターフォールです。
スタイルシートとスクリプトを </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()
で場合別けをしています。
DNS プリフェッチを設定
上記のコードだけでもいいのですが、ドメインの名前解決だけ先に行っておくことで少しだけ広告の読み込みが早くなります。
<head>
内に以下を設定します。
<link rel='dns-prefetch' href='//lh3.googleusercontent.com' />
<link rel='dns-prefetch' href='//pagead2.googlesyndication.com' />
<link rel='dns-prefetch' href='//adservice.google.co.jp' />
<link rel='dns-prefetch' href='//adservice.google.com' />
<link rel='dns-prefetch' href='//googleads.g.doubleclick.net' />
WordPress なら function.php に以下を書き込めば上記のコードを出力してくれます。同じく is_single()
で場合分けしています。
//DNSプリフェッチ
function add_resource_hints( $hints, $relation_type ) {
if( is_single() ){
if ( 'dns-prefetch' === $relation_type ) {
$hints[] = '//lh3.googleusercontent.com';
$hints[] = '//pagead2.googlesyndication.com';
$hints[] = '//adservice.google.co.jp';
$hints[] = '//adservice.google.com';
$hints[] = '//googleads.g.doubleclick.net';
}
}
return $hints;
}
add_filter( 'wp_resource_hints', 'add_resource_hints', 10, 2 );
施策後のウォーターフォール
施策後のウォーターフォールでは画面にアクセスしたときは 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 のスコアが上がるとは思いませんでした。体感はそんなに変わらないのでやった意味があるのかわかりませんがなんとなく気分がいいです。そのほかの高速化については以下の本がまとまってわかりやすいです。