Async Sharing Buttons (G+, Facebook, Twitter)

Some of these services already (smartly) provide their scripts in an async fashion, this just combines them into more efficient, organized, and understandable code.

(function(doc, script) {
  var js, 
      fjs = doc.getElementsByTagName(script)[0],
      frag = doc.createDocumentFragment(),
      add = function(url, id) {
          if (doc.getElementById(id)) {return;}
          js = doc.createElement(script);
          js.src = url;
          id && ( = id);
          frag.appendChild( js );
    // Google+ button
    // Facebook SDK
    add('//', 'facebook-jssdk');
    // Twitter SDK

    fjs.parentNode.insertBefore(frag, fjs);
}(document, 'script'));

I found it going through some site code and I forget exactly who originally did it but it seems like a Nicolas Gallagher or Mathias Bynes kind of thing. Correct me if I'm wrong.

You'll need the HTML in place for the scripts to put their stuff:

<a href="" class="twitter-share-button" data-count="horizontal">Tweet</a>

<div class="g-plusone" data-size="medium" data-count="true"></div>

<div id="fb-root"></div>
<div class="fb-like" data-send="false" data-layout="button_count" data-width="1" data-show-faces="false" data-action="recommend"></div>


  1. James Brown
    Permalink to comment#

    Why are you passing ‘script’ into the anonymous function?

    • Mathias Bynens
      Permalink to comment#

      That’s explained here: In this case, there’s no real run-time performance gain, it only saves a few bytes. Passing document avoids scope lookups though, and thus slightly improves run-time performance.

    • James Brown
      Permalink to comment#

      So, it would seem if he had made the incoming parameter a single letter, and especially since he used it more than once, it would save quite a bit more bytes. In this example, it doesn’t really help much…

    • flora
      Permalink to comment#

      I am supposed to write tag to your codes?
      Because I maybe stupid but they are not working for me

  2. jswebschmiede
    Permalink to comment#

    i like that, very usefull. Thank you very much.

  3. Mike Cravey
    Permalink to comment#

    One thing worth mentioning is that these will still hold up document complete (loaded). Aaron Peters refactored it slightly to wait on window load before firing to handle that.

    • Mathias Bynens
      Permalink to comment#

      That change doesn’t affect the user experience at all, though. See the comments on that article.

  4. Rahul Bansal
    Permalink to comment#

    There is a better way to add button!
    Basically create a locally hosted image sprite for all social icons. Put some API for count fetching. You will get much lighter and cleaner code (without iframes, etc)

    We already have a WordPress plugin to add sharing buttons for various social sites as proof of concept.

    Its called rtSoical –

  5. Koundeenya
    Permalink to comment#

    Thats really great to see this! Perfect combination of javascript with the right CSS code.
    Better than plugins because plugins usually increase the load time

  6. Bali Balo

    Why using id && ( = id); instead of if(id) = id; ?
    It doesn’t save bytes and the second one is a bit more readable, I think.

    Nice script anyway.

  7. Phil
    Permalink to comment#

    Little question: the script works like a charm but the trade off for me was giving up the twttr variable. Now I’d like to implement the google analytics for the twitter button (Link) so I really need it.
    What is on your eyes the best way of getting this capability while remaining generic and clean at the same time?

  8. Matt
    Permalink to comment#

    I’m a newbie in ASYNC and maybe I don’t completely understand it but…

    I did a small test to compare load time/size using ShareThis ( and the ASYNC method above loading in all the needed JS for sharing…

    With 5 sharing buttons (FB, LinkedIn, Pinterest, Google + and Twitter) the load size increased about 5% using the method above.

    Might be worth doing your own test but this answered some questions for me. I concluded that using ShareThis helped performance when using several share buttons. I can’t say the same in the case of using one or two select buttons.

    Would this be a proper conclusion or am I missing the point of ASYNC?

  9. george
    Permalink to comment#

    hello Async Loaded the jquery.min.js but working?? this

    script async src=’/jquery/1.8.2/jquery.min.js’ type=’text/javascript’/

    no works :( and this
    (function(){var po=document.createElement(‘script’);po.type=’text/javascript’;po.async=true;po.src=’ bla bla’;var s=document.getElementsByTagName(‘script’)[0];s.parentNode.insertBefore(po,s)})();
    eny idea?,,

  10. David
    Permalink to comment#

    In answer to Matt,

    As far as I know, the purpose of Async code is not to make the social buttons load faster or smaller, but rather to prevent the load time of the social buttons from slowing down the load time of the rest of the page. Since the social buttons have to contact several different servers (facebook, google, twitter,etc.) it can take extra time to load those. In a traditional loading manner, the whole page stops loading until the buttons load. This way, the buttons and the page can load at the same time, so that the load speed of the major page content is not negatively affected.

    Great article. Thanks Chris.

  11. Muhammad Nouman Khalid
    Permalink to comment#

    Can we use Google Analytics monitoring code too into this one and make them a single script to host into an external .js file.

    Will this technique decreases loading speed of

  12. Redfredg
    Permalink to comment#

    Hi Chris Coyier ,
    I am planning to lunch a site in this month. I want it to go mobile. Which framework to you suggest?

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences like this:

  function example() {
    element.innerHTML = "<div>code</div>";

We have a pretty good* newsletter.