Lazy Loading Responsive Adsense Ads

Avatar of Osvaldas Valutis
Osvaldas Valutis on (Updated on )

You’ve been hard at work optimizing your site. You’ve already done things like lazy-loading Google Maps and been wondering if there was anything else you could do. For example, is there anything we can do to improve the loading of ads? Good news, there is some things you can do. You can respect the user’s mobile data plan by loading ads only when they are likely to appear in the viewport zone. You can also serve ads in the right size in accordance with the screen of the device. That would be nice of you. That would not only be responsive but also responsible.

The Problem

The nature of Google Adsense is that the ads, along with the script, file are loaded automatically: this may unreasonably slow down the appearance of the other important things, like styles, fonts, or other scripts.

Google Adsense: no lazy load

Moreover, the correct ad size is determined only once right before the ad load. It means that if the user resizes the browser or rotates the tablet, the ad size remains the same and most likely doesn’t fit the context anymore.

Google Adsense: not responsive

The Arguments

  • There are many factors that Google Adsense considers for monetization, but “Click Through Rate” plays a major role in revenue. Therefore, focusing on clicks rather than just views in the long term may result in increased revenue. You can get more clicks by making your site look and feel trustworthy to a user. You can get that trust by prioritizing which parts of your website to load first. Serving ads first, instead of the actual content that the user came for, is a way to the decreasing ad clicks and impressions.
  • Logically, Google Adsense shouldn’t track an ad view when the ad never gets into the zone of the viewport. I don’t know if Google Adsense has this kind of tracking yet, but since the technology is JavaScript-based, they have all the means to do it.
  • It is typical for smartphone and tablet users to constantly switch between portrait and landscape modes until they find the most comfortable one. Providing the most appropriate ad size for each mode improves the possibility of getting more clicks.

The Solution

I’ve made a JavaScript plugin to help. It helps to lazy loads the ads:

Google Adsense: with lazy load

No matter where the ad is, above or below the viewport, it won’t get loaded if the ad is out of view.

It also helps to resize the ads:

Google Adsense: responsive

The banner gets reloaded at particular breakpoints.

JavaScript

The plugin itself is a tiny piece of JavaScript code, and I made two versions of it: vanilla and jQuery. I called it adsenseLoader. You can grab the files here:

This is how you initialize it:

// vanilla
var instance = new adsenseLoader( '.adsense' ); // accepted argument types: Selector String, Element, NodeList, Array
 
// jQuery
$( '.adsense' ).adsenseLoader();

You can also customize it. The default options are:

var options =
{
    laziness: 1,
    /*
        @int (<=0)
        This sets the laziness of loading the ads: (viewport height) * laziness . For example:
        0 – ad load starts when at the least a tiny part of it gets in the viewport;
        1 – ad load starts when the distance between the ad and the viewport is no more than the height of the viewport;
        2 – 2x viewports, etc.
    */
 
    onLoad: false
    /*
        @bool
        A callback function which is fired when the ad is fully loaded.
        A single argument (object) of the ad element is passed. For example:
        onLoad: function( ad )
        {
            alert( ad.getAttribute( 'data-ad-slot' ) + ' ad is loaded' );
        }
    */
};
 
// vanilla
var instance = new adsenseLoader( '.adsense', options );
 
// jQuery
$( '.adsense' ).adsenseLoader( options );

Moreover, there’s a methodical function destroy, which does as it’s named: destroys the ad and brings back the corresponding DOM fragment to the default state. You can call the function for the whole instance as well as for single elements:

// vanilla
var instance = new adsenseLoader( '.adsense', options );
 
instance.destroy();
// or
document.querySelectorAll( '.adsense' )[ 0 ].adsenseLoader( 'destroy' );
 
 
// jQuery
$( '.adsense' ).adsenseLoader( options );
 
$( '.adsense' ).adsenseLoader( 'destroy' );
// or
$( '.adsense' ).eq( 0 ).adsenseLoader( 'destroy' );

Lastly, you can change a few more options that have a global impact across all of the plugin instances. You can call the function anywhere, but it’s designed to be used before creating any instance of the plugin. The default options are:

var options =
{
    scriptUrl: '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
    /*
        @string (url)
        URL for Google Adsense's executive script file
    */
 
    throttle: 250
    /*
        @int (miliseconds)
        This defines how often the plugin should make
        calculations during the processes such as resize
        of a browser's window or viewport scroll.
        250 means that this happens 4 times in a second.
    */
};
 
// vanilla
adsenseLoaderConfig( options );
 
// jQuery
$.adsenseLoaderConfig( options );

HTML

Here we have to simplify Adsense code snippet by leaving only two parameters and put it all into a container element:

<div class="adsense">
  
</div>

CSS

This part is responsible for controlling the size of ads. Using CSS, we will define the width and the height of the container element with the exact dimensions for the expected ad. With the help of media queries and a pseudo element, we’ll set the guides for the plugin which will later be able to determine when to resize/reload an ad.

.adsense {
    width: 970px;
    height: 90px;
    display: block;
}
.adsense:before { display: none !important; }
.adsense ins    { width: 100%; height: 100%; display: block; }
 
@media screen and ( max-width: 1024px ) {
    .adsense        { width: 728px; height: 90px; }
    .adsense:before { content: '1024'; }
}
 
@media screen and ( max-width: 800px ) {
    .adsense        { width: 468px; height: 60px; }
    .adsense:before { content: '800'; }
}

/* etc. */

Luckily, Adsense itself is able to pick the right banner size according to the given dimensions. The width and height properties for selector .adsense determine whatpseudo-element expecting.

Using media queries and the pseudo element ::before, we tell the plugin when it is supposed to reload the ad. The JavaScript part checks for differences for content values. An ad is automatically reloaded when a difference is detected. You can use any different integers across the media queries. In my examples, I equated the values to the media queries’ width parameters for an easier maintenance.

Resizing the banners is a job split across two disciplines: CSS is the logic and JavaScript is the execution.

Demo

Remember that if you’re using an ad blocker that blocks AdSense, you may not see this work correctly.

See the Pen Lazy-Loading Responsive Adsense Ads by Osvaldas (@osvaldas) on CodePen.

You are welcome to follow and contribute to the project on GitHub.

Disposing Multiple Ads

Here’s a quick tip on how to manage multiple differently sized ads. Say we have two banners: one in the content area and another in the sidebar. We can assign different class names for each:

<div class="adsense adsense--main">...</div>
&nbsp;
<div class="adsense adsense--side">...</div>

Now we can define common styles for .adsense and individual styles for .adsense--main and .adsense--sidebar, like this:

.adsense{
    display: block;
}
.adsense:before     { display: none !important; }
.adsense ins        { width: 100%; height: 100%; display: block; }
 
.adsense--main      { width: 728px; height: 90px; }
.adsense--side      { width: 336px; height: 280px; }
 
@media screen and ( max-width: 1024px ){
    .adsense--main          { width: 468px; height: 60px; }
    .adsense--main:before   { content: '1024'; }
}
 
@media screen and ( max-width: 800px ){
    .adsense--side          { width: 250px; height: 250px; }
    .adsense--side:before   { content: '800'; }
}

Ad Loading Indication or Taking Advantage of onLoad()

You can indicate the loading process in a few ways: provide a placeholder image, add text, border, background or anything else that best meets your design direction and is visible until the ad loads:

Google Adsense Loading Indication Preview

To start with, let’s add extra an HTML element and some styling, which basically adds an overlay with text “Loading…” above the ad:

<div class="adsense">
  <ins data-ad-client="ca-pub-4676533344420647" data-ad-slot="5741144487"></ins>
  <p class="adsense__loading"><span>Loading&hellip;</span></p>
</div>
.adsense {
    position: relative;
}
    .adsense__loading {
        width: 100%;
        height: 100%;
        background-color: rgba( 255, 255, 255, .9 );
        display: table; /* for vertical centering */
        position: absolute;
        top: 0;
        left: 0;
    }
    .adsense--loaded .adsense__loading { display: none; }
 
        .adsense__loading span {
            text-align: center;
            vertical-align: middle; /* for vertical centering */
            display: table-cell; /* for vertical centering */
        }
Google Adsense Loading Indication Stack

Using the callback function onLoad() we can add the class adsense--loaded which is responsible for hiding the .adsense__loading element:

// vanilla
var instance = new adsenseLoader( '.adsense',
{
    onLoad: function( ad )
    {
        if( ad.classList )
            ad.classList.add( 'adsense--loaded' ); // IE 10+
        else
            ad.className += ' ' + 'adsense--loaded'; // IE 8-9
    }   
});
 
// jQuery
$( '.adsense' ).adsenseLoader(
{
    onLoad: function( $ad )
    {
        $ad.addClass( 'adsense--loaded' )
    }
});
Google Adsense Loading Indication Animated Stack

Thanks for reading and being a responsible web designer/developer.