Creating static social share buttons

Social networks are everywhere online. Share, like and tweet buttons are popping up on a lot of webpages these days. The social buttons however have a big impact on the performance of a website. They load a ton of resources and slow down websites.

In this post I'll tell you why I hate these social buttons so much. I'll also walk you through the process of building the static share buttons that I use on my website.

Impact on performance

So why do I hate these social buttons so badly? Let me demonstrate my hate towards these buttons. I created two empty HTML pages and inserted the code for a Share button and Tweet button. The results speak for themselves:

Facebook share button Load Time 1.42 seconds
Requests 8
Transfered 147 KB
DOM Content Loaded 243 ms
Twitter Tweet button Load Time 2.74 seconds
Requests 6
Transfered 54.1 KB
DOM Content Loaded 224 ms

Simply adding a Facebook Share button makes your website load 1.42 seconds longer and 147KB bigger. Keep in mind that I disabled my cache to perform these tests. Most people probably have a cached version of these resources, so they load faster. These buttons also load asynchronously so they don't block page rendering (thank God!).

Still, they add a lot of bulk to your webpages. I compared these numbers with those for my website's homepage. I cried when I saw the results:

Savjee.be (with Google Analytics enabled) Load Time 494ms
Requests 5
Transfered 21.7 KB
DOM Content Loaded 314ms
Savjee.be (with Google Analytics disabled) Load Time 295ms
Requests 3
Transfered 9.7 KB
DOM Content Loaded 287ms

(My website uses Gzip compression to make sure pages are as small as possible. Read more here.).

If I would integrate a share button on my homepage, I would make my page 6 times heavier (going from 21.7KB to 168.7KB). And that's only the Facebook button! Let's say I want to add Twitter and Google+ as well.

I'm sorry, but that's unacceptable to me!

Many might not care about loading an additional 57 or 147 KB. But I do! I hate loading more resources than actually necessary. These buttons might not have a big impact on modern computers with high-speed internet connections. The story is different when you load these social buttons on a smartphone with a much slower Egde or 3G connection. I want my website to be fast no matter where you live, what device you're using or how fast your internet connection is.

Easy solution: static!

The simplest solution to this problem is using static share buttons. I've used a static Tweet button on my website for a couple of months now. The idea is easy: create a button and use the Twitter share URL like this:

<a href='http://twitter.com/share?url=URL_TO_PAGE&text=TITLE_TO_SHARE&via=TWITTER_USERNAME' class='button'>Tweet a link to this page</a>

This share URL takes 3 parameters:

Facebook has a similar URL that allows you to share stories:

https://www.facebook.com/sharer/sharer.php?u=URL_TO_PAGE

Making the buttons count!

I also want my static social buttons to show the amount of shares or tweets my page got. This involves some Javascript and JSONP magic. (And yes, I realize that this makes my buttons dynmic, not very static…)

JSONP or “JSON with padding” is a Javascript technique that allows you to fetch data from a server on a different domain. Technically this isn't allowed by most browsers. JSONP takes advantage of the fact that browsers do not enforce the same-origin policy on <script> tags.

Both Facebook and Twitter have a URL that let's you check how many shares or tweets a given link has. Twitter's URL is not officially supported (read: might break in the future) but has been working for quite some time. You can use one of the following URLs:

http://graph.facebook.com/?id=http://www.google.com/&callback=myFunction
http://urls.api.twitter.com/1/urls/count.json?url=http://www.google.com/&callback=myFunction

Note the callback parameter. This tells the API to call a specific Javascript function on your page with the JSON results you're interested in. Here's the example output of both URLs:

// Facebook's response
myFunction({
"id": "http://www.google.com/",
"shares": 10121803,
"comments": 943
});

// Twitter's response
myFunction({
count: 21992829,
url: "http://www.google.com/"
})

Here is the piece of JSONP Javascript that I currently use to get the tweet and share count:

var StaticShareButtons = {
twitterButton: document.querySelector('.share-button-twitter'),
facebookButton: document.querySelector('.share-button-facebook'),

init: function(){
this.injectScript('http://urls.api.twitter.com/1/urls/count.json?url=' +
escape(this.twitterButton.dataset.shareUrl) + '&callback=' + 'StaticShareButtons.processTwitter');

this.injectScript('http://graph.facebook.com/?id='+
escape(this.facebookButton.dataset.shareUrl) +'&callback=StaticShareButtons.processFacebook');
},

injectScript: function(url){
var script = document.createElement('script');
script.async = true;
script.src = url;
document.body.appendChild(script);
},

processTwitter: function(data){
if(data.count != undefined){
this.twitterButton.querySelector('.count').innerHTML = data.count;
}
},

processFacebook: function(data){
if(data.shares != undefined){
this.facebookButton.querySelector('.count').innerHTML = data.shares;
}
}
}

StaticShareButtons.init();

I borrowed most of the code from David Walsh's blog post. I just wrapped everything in one object.

Note that you can use a regular Ajax request for retrieving the share count from Facebook. This works because Facebook sets the Access-Control-Allow-Origin header to *. Sadly you can't use the same technique for Twitter since they don't set that header. Shame!

Designing the buttons

I started looking around for a design for my social buttons. I wanted a simple design that's flat and didn't include any images (retina-friendly!). I found a nice set of social buttons on Dribble designed by Maki Myers. I downloaded his code and refactored it so it doesn't use floats or relative positioning.

Here's the HTML code that I use on my website for the social buttons:

<div class="share-button share-button-facebook" data-share-url="{{'http://www.savjee.be' | URLEncoding}}{{page.url | URLEncoding}}">
<div class="box">
<a href="https://www.facebook.com/sharer/sharer.php?u={{'http://www.savjee.be' | URLEncoding}}{{page.url | cgi_escape}}">
<span class='share'>Share</span>
<span class='count'>0</span>
</a>
</div>
</div>

There are some Liquid tags in this piece of HTML code that are being filled in by Jekyll. I previously wrote a blog post on static blogging with Jekyll. By default URLEncoding is not available in the Liquid templating engine but you can add it using this simple filter.

My modified CSS code looks like this:

.share-button-container{
text-align:center;
margin: 20px 0;
padding: 10px 0;
border-top: solid 1px #e4e4e4;
border-bottom: solid 1px #e4e4e4;
}

.share-button-container p{
margin:0px 0 10px 0;
}

.share-button {
margin-left: 20px;
}

.share-button a{
text-decoration:none;
}

.share-button, .share-button .count{
display:inline-block;
}

.share-button .count, .share-button .share {
font-family:"Helvetica Neue";
font-weight:700;
text-decoration:none;
text-align:center;
}

.share-button .count {
background-color:#F1F3F6;
color:#333;
font-size:12px;
line-height:25px;
margin-left:4px;
text-transform:uppercase;
min-width:40px;
}

.share-button .share {
-webkit-border-radius:2px;
-moz-border-radius:2px;
border-radius:2px;
color:#FFF;
display:inline;
font-size:13px;
width:40px;
padding:4px 8px;
}

.share-button-twitter .share {
background-color:#00ABF0;
}

.share-button-facebook .share {
background-color:#3b5998;
}

.share-button-googleplus .share {
background-color:#F53424;
}

.share-button-twitter .share:active,.share-button-facebook .share:active,.share-button-googleplus .share:active {
background-color:#353535;
}

The buttons are rendered correctly on every type of device. No need for responsive CSS. However, the only thing I did for my website is increase the size of the buttons for mobile devices. This makes them easier to tap:

/* Much more easy to tap on a big button! */
@media (max-width: 925px) {
.share-button .share{
font-size:15px;
padding: 8px 16px;
}

.share-button .count{
font-size:14px;
line-height: 32px;
}
}

Result & Limitations

Here's a screenshot of the finished product: Screenshot of the static buttons

You can see them in action at the bottom of each blog post on my website.

You can have static share buttons for a number of social networks. Want Google+, LinkedIn, Pintrest, ...? Then check out this gist for additional information on other social networks.

Sadly, you can't have a static Like button. This requires the Facebook SDK.

Source

The source code is available on GitHub. Check it out: https://github.com/Savjee/static-social-buttons.

Posted on

Subscribe to my newsletter

Monthly newsletter with cool stuff I found on the internet (related to science, technology, biology, and other nerdy things)! Check out past editions.