How to lazy load Google ads using native javascript!

I recently made a post on how I lazy load my Disqus comments. I did this because my website was performing poorly when I analyzed it using Google pagespeed. Disqus was not the only thing that was performing poorly, Google Adsense was killing my load time! I therefore decided to try and find a way to lazy load these ads. On a sidenote I also disabled and removed the script for auto ads, as this was slowing down my website as well.

DISCLAIMER: I do not know how Google stands on this method for lazy loading their ads. They seem to have their own way. Whether this can lead to action against you and your Adsense account I do not know, so far nothing has happened to me. If you have any information or suggestions on this, please let me know in the comments down below. I am writing this, as I would very much dislike if my attempt to help you achieve better loading time leads to actions against you

Let us get right into it, the only thing I add to my HTML to make this work is this:

<div class="lazy-load-ad"></div>

This of course also requires some javascript to work. However I like to keep this element as simple as possible so if I ever decide to switch out Adsense I hopefully can do this easier. Above I have made a simple div element with a class called lazy-load-ad, the magic happens in the javascript:

var elements = document.getElementsByClassName('lazy-load-ad');
if (!elements.length)
	return;

var googleAdScriptAppended = false;

window.addEventListener('scroll', function (e) {
	var currentScroll = document.scrollingElement.scrollTop;

	for (var i = 0; i < elements.length; i++) {
		var element = elements[i];
		if ((currentScroll > element.getBoundingClientRect().top - 100)) {

			if (!googleAdScriptAppended) {

                googleAdScriptAppended = true;
				var scriptElement = document.createElement("script");
                scriptElement.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
				document.body.appendChild(scriptElement);
			}

			if (window.adsbygoogle) {
				element.classList.remove('lazy-load-ad');
				element.classList.add('lazy-loaded-ad');
				element.innerHTML = getAdsenseCode();
                loadAd();

				elements = document.getElementsByClassName('lazy-load-ad');
			}
		}
	}
}, false);

//TODO change this to your ad unit!
var getAdsenseCode = function () {
	return '<div class="addsense-add">' +
              '<ins class="adsbygoogle"' +
                    'style="display:block; text-align:center;"' +
                    'data-ad-format="fluid"' +
                    'data-ad-layout="in-article"' +
                    'data-ad-client="ca-pub-2997413406307797"' +
                    'data-ad-slot="2538409688">' + 
              '</ins > ' +
           '</div>';
};

var loadAd = function () {
	(adsbygoogle = window.adsbygoogle || []).push({});
};

The above is written in native/vanilla javascript and requires no external libraries. It goes as this: I first check if there are to be any ads on the page by checking if there are elements with the lazy-load-ad class. I run this script on all my pages and some may not contain ads, therefore I have this check. If there are ads I attach an event to the scroll bar and if we are a 100 pixels from an ad I add the Google Adsense scripts and load that ad. The code checks if the Google Adsense script have already been loaded, so they are not loaded more than once. When I load the ad I change the class to lazy-loaded-ad so it is not loaded several times.

You may think that it is a huge waste to have the loadAd() method separate as it is just one line. My reason for this is that it is very hard to understand what that line does, so I try to make it explicit. The (adsbygoogle = window.adsbygoogle || []).push({}); line in the code is actually what loads the ad, it tells the Adsense API that there is an ad to load on the page.

In the above you need to change the ad unit. The above ad unit is mine which you also can see on this page if you inspect the HTML, it is lazy loaded as you will see as you scroll down the page.

That is it, please let me know what you think in the comments down below!