- 2012.04.24
- IEでコールバックが動作しない不具合がありましたので修正しました(参考 : 外部JavaScriptの動的ロード – 0xFF)。
ソーシャル全盛期の昨今、どのWebページにも設置されているソーシャル系のシェアボタン。僕のブログにも設置していますが、Facebook、Twitter、Google+1、はてな…と数が増えて重い重い。記事の一覧ページでそれぞれにボタンを表示させたらそれはもうすごく重い。これではせっかくページに来てくれたユーザーも離脱してしまいますね。
非同期読み込みとは
どうにか速度を改善できないか調べていたところ、下記のような記事を発見。
ようは、普通に下記のようにJSを読み込むと、読み込みが完了するまでその下のページの表示が止まってしまうと。
<script type="text/javascript" src="http:..."></script>
そこで、動的にscriptタグを組み立てて非同期で読み込むことで、ページの表示を遅らせること無くJSを読み込む、という手法がとられることが多いようです。FacebookやGoogle+1でもそのような読み込み方法が推奨されています。
Facebookの場合
(function(d){ var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; if (d.getElementById(id)) {return;} js = d.createElement('script'); js.id = id; js.async = true; js.src = "//connect.facebook.net/ja_JP/all.js"; ref.parentNode.insertBefore(js, ref); }(document));
非同期読み込みコード
それぞれのソーシャルボタンのスクリプトを全て非同期にしてしまえば良いのですが、似たようなコードを何度も書くことになるので可読性が悪く管理も煩雑になってしまいます。そこで、非同期読み込みのコードを関数化して、すっきりしたコードでいろいろなJSを読み込めるようにしてみました。
<script type="text/javascript"> ( function( doc, script ) { var js; var fjs = doc.getElementsByTagName( script )[0]; var add = function( url, id, o ) { if ( doc.getElementById( id ) ) { return; } js = doc.createElement( script ); js.src = url; js.async = true; js.id = id; fjs.parentNode.insertBefore( js, fjs ); if ( window.ActiveXObject && o != null ) { js.onreadystatechange = function() { if ( js.readyState == 'complete' ) o(); if ( js.readyState == 'loaded' ) o(); }; } else { js.onload = o; } }; // Google+1 window.___gcfg = { lang: "ja" }; add( 'https://apis.google.com/js/plusone.js' ); // Facebook add( '//connect.facebook.net/ja_JP/all.js', 'facebook-jssdk', function() { add( 'http://static.ak.fbcdn.net/connect.php/js/FB.Share', 'facebook-share' ); }); // Twitter add( '//platform.twitter.com/widgets.js', 'twitter-wjs' ); // はてな add( 'http://b.st-hatena.com/js/bookmark_button.js', 'hatena-js' ); }( document, 'script' ) ); </script>
関数addは、JSのパス、script要素に付与するID、コールバック関数を引数にとります。上記の例では、FacebookのSDKを読み込んだ後、シェアボタンのJSも読み込むようにしています。Analyticsなどのスクリプトも同じような感じで追加できるかと思います。
一応、測定結果
管理しているページでページの表示速度を測定したところ、およそ30%の速度向上が見られました。
※Firefox3.6、Firebugで計測。前:平均56s(onload平均27.6s)->後:平均39s(onload平均19.4s)