Better social widget lazy loading

by Taylor Fausak on

Last month, I streamlined my blog by lazy loading social widgets. I liked the results but felt that I could do better. A Hacker News comment tipped me off to Socialite.js. That script reminded me that onhover is more appropriate than onscroll. So I updated my script.

I held off writing a post describing what I changed because the core idea is the same: don’t load the widgets until the user wants them. However, a couple people emailed me about my new approach. In addition, Oliver Reichenstein urged webmasters to sweep the sleaze; lazy loading widgets addresses the technical concerns (privacy, load times, scrolling performance) with ease.

Markup

Typically, loading a social widget like the Google +1 button looks like this:

<div class="g-plusone" data-size="tall"></div>

Waiting to load the widget until the user hovers over it requires some additional markup. The widget needs a placeholder, which will be used until the user hovers, and for clients with JavaScript disabled. Both the widget and the placeholder need to be wrapped in a container.

<div class="social-widget google-widget">
    <a href="#google" id="google-widget">
        +1
    </a>
    <div class="g-plusone" data-size="tall"></div>
</div>

Of course, #google should be replaced with a link to Google’s sharer. Stack Overflow covers adding a Google +1 link without JavaScript. That answer also covers Facebook and Twitter.

Styles

Before the actual widgets load, the placeholder needs to look pretty. Fortunately, each widget has a distinctive color and verb associated with it. Facebook’s Like is blue (#3b5b99), Google’s +1 is orange (#dd4b39), and Twitter’s Tweet is light blue (#33ccff). Also, the widgets are all about the same size. They’ll all fit in a 62-by-55 pixel rectangle.

#facebook-widget,
#google-widget,
#twitter-widget {
    color: #ffffff;
    display: block;
    line-height: 62px;
    text-align: center;
    text-decoration: none;
    width: 55px;
}
#facebook-widget { background: #3b5b99; }
#google-widget   { background: #dd4b39; }
#twitter-widget  { background: #33ccff; }

Now the placeholders won’t be an eyesore before the actual widgets load.

Scripts

Since the markup for the widgets is already in the page, all that needs to be done is load the appropriate JavaScript library. So when the user hovers over the +1 widget, load Google’s +1 library. In addition, the placeholder should be removed, since it’s obsoleted by the actual widget.

var element, script;
element = document.getElementById('google-widget');
element.onmouseover = function () {
    this.onmouseover = null;
    this.parentNode.removeChild(this);
    script = document.createElement('script');
    script.async = true;
    script.src = '//apis.google.com/js/plusone.js';
    document.body.appendChild(script);
};

That’s all there is to it! Loading the other social networks’ widgets is very similar.

Post Script

I’m very happy with this approach. It has none of the drawbacks of my previous version. It also plays nicely with clients that don’t run JavaScript, including text-only browsers. It works great on mobile, too, where the first tap is interpreted as a hover.

This blog uses this technique, so just scroll down for an example. If you want to see exactly how it’s implemented, check the source. If you have any complaints or recommendations, please let me know.