ソーシャル系ボタンの表示を非同期化してブログの表示を高速にする方法

付箋がないと本が読めなくなりました。ago@kyo_ago)です。

先日リニューアルした弊社デザイナーブログの表示を高速化したのでその方法を紹介したいと思います。

KAYAC DESIGNER'S BLOG

元々トップページに記事が12件表示され、その記事毎にFacebook、Google Buzz、はてブ、Topsy(Twitter)を読み込んでいたのですが、その結果12件*4件=48件の外部APIアクセスが発生し表示に10秒程度かかっていました。

しかし、実際に外部APIを使用している部分は最初は表示されず、記事をクリックしてから表示されるようになるため、以下のようなJSを使用して各記事を表示する段階で外部APIアクセスを行うようにしたところ、トップページの表示が3秒程度に高速化しました。

// for topsy init=preload 
window.preload = function () {};
jQuery('body').append('<script src="http://cdn.topsy.com/topsy.js?init=preload"></script>');
$('.fncEntryToggle').live('click', function () {
    var self = $(this).find('.boxShare');
    // for facebook 
    var facebook = self.find('.facebook a');
    facebook.replaceWith('<iframe src="'+facebook.attr('href')+'" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:85px; height:21px;" allowTransparency="true"></iframe>');
    // for google buzz 
    self.find('.google-buzz-button').not('.done').addClass('done').append('<script type="text/javascript"http://www.google.com/buzz/api/button.js"></script>');
    // for hatebu 
    var hatebu = self.find('.hatebuImage');
    hatebu.replaceWith('<img src="'+hatebu.attr('href')+'" />');
    // for topsy 
    var topsy = self.find('.topsy_widget_data');
    (function () {
        var write = document.write;
        try {
            document.write = function (span) {
                topsy.append(span);
            };
            topsyWidgetPreload({
                "url": topsy.find('[name="url"]').val(),
                "title": topsy.find('[name="title"]').val(),
                "nick": topsy.find('[name="nick"]').val()
            });
            topsy.removeClass('topsy_widget_data')
        } finally {
            document.write = write;
        };
    })();
});

MTのタグ部分は以下のように設定しています。

<ul>
<li class="twitter"><div class="topsy_widget_data" style="display:inline;"><input type="hidden" name="url" value="<$MTEntryLink$>"><input type="hidden" name="title" value="<$mt:EntryTitle encode_url='1'$>"><input type="hidden" name="nick" value="kayac_design"></div></li>
<li><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="small-count" data-url="<$MTEntryLink$>" rel="external">buzz</a></li>
<li class="facebook">
<a href="http://www.facebook.com/plugins/like.php?href=<$MTEntryLink encode_url='1'$>&amp;layout=button_count&amp;show_faces=false&amp;width=120&amp;action=like&amp;colorscheme=light&amp;height=21"></a>
</li>
<li><a href="http://del.icio.us/post?v=4;url=<$MTEntryLink$>;title=<$mt:EntryTitle encode_url="1"$>" title="このエントリーをブックマーク" rel="external"><img src="http://tech.kayac.com/img/ico/share/delicious.png" width="22" height="22" alt="del.ici.ous"></a></li>
<li><a href="http://b.hatena.ne.jp/my/add.confirm?url=<$MTEntryLink$>" title="このエントリーをブックマーク" rel="external" class="external"><img src="http://tech.kayac.com/img/ico/share/hatebu.png" width="16" height="12" alt="はてなブックマーク"></a> <a href="http://b.hatena.ne.jp/entry/<$MTEntryLink$>" rel="external" class="external"><a href="http://b.hatena.ne.jp/entry/image/<$MTEntryLink$>" rel="external" class="hatebuImage"></a></a></li>
</ul>

コードとしてはFacebook、Google Buzz、はてブは普通にhtmlの置き換えで対応出来ますが、Topsy(Twitter)は公式ドキュメントでも「動的な読み込みはサポートしない」と書かれていたため、document.writeを書き換えてやや強引に対応しました。
(ちなみにTopsyは非同期で読み出す場合もclass="topsy_widget_data"が必要なので注意してください)

Topsy Retweet Button for Web Sites

カヤックでは速度にこだわる技術者も募集しています!