延迟加载Google Auto Ads加速Hexo

# 提升Hexo NexT主题加载速度 中留了个尾巴,优化到最后发现最影响PageSpeed Insights得分的竟然是Google Auto Ads。 这里 有个有意思的讨论,说加上auto ads之后页面加载得分显著变低,采纳答案说“你啥也做不了,也不用care”,下面有人反对这个观点,加载速度评测认为网站慢就会导致搜索排序降低。我赞成后者的观点,风一样的加载速度即我所欲也,本来无一物,何处惹尘埃!

先看下优化之前的Mobile得分: PSI Mobile

一眼看上去似乎有很多问题,其实就是Google Auto Ads的锅,Reduce unused JavaScript一项中有不少Google Ads加载的资源。分析加入Auto Ads的script:

<script data-ad-client="ca-pub-2660281922577700" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

这段script虽然是异步,从效果来看还是影响了页面加载。按 这里 尝试把async改为defer,没什么作用。

页面加载完毕后加载Ads

参考这里 # How to Setup Lazy Load for Google AdSense Ad units? ,在window.onload之后再加载Ads script:

<script>
   window.onload = function(){
       ...
   };
</script>

有如下实现:

<script type="text/javascript">
    function downloadJsAtOnload() {
        var element = document.createElement("script");
        element.setAttribute("data-ad-client", "ca-pub-2660281922577700");
        element.async = true;
        element.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
        document.body.appendChild(element);
    };
    if (window.addEventListener)
        window.addEventListener("load", downloadJsAtOnload, false);
    else if (window.attachEvent)
        window.attachEvent("onload", downloadJsAtOnload);
    else window.onload = downloadJsAtOnload;
</script>

最后几行是为了兼容IE8以下版本,参考:# Correct usage of addEventListener() / attachEvent()

这段代码经测试也不能提高PSI得分,可能PSI会等整个页面的script加载完毕后才算数。

延时加载Ads

那就再狠一些,5秒后再加载广告脚本,用setTimeout()延时:

<script>
   setTimeout(function(){
       ...
   }, 5000);
</script>

最终实现:

<script type="text/javascript">
    setTimeout(function downloadJsAtOnload() {
        var element = document.createElement("script");
        element.setAttribute("data-ad-client", "ca-pub-2660281922577700");
        element.async = true;
        element.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
        document.body.appendChild(element);
    }, 5000);
    if (window.addEventListener)
        window.addEventListener("load", downloadJsAtOnload, false);
    else if (window.attachEvent)
        window.attachEvent("onload", downloadJsAtOnload);
    else window.onload = downloadJsAtOnload;
</script>

优化之后的得分: PSI Mobile