WordPress.com Stats の JavaScript を並列読み込み対応にする

昨日のエントリの続き。
WordPress.com Stats 日本語版の JavaScript を並列読み込み対応にしてみましょう。

WordPress.com Stats 日本語版で JavaScript を読み込み、動作用の JavaScript をフッタに書き出しているのは、stats.php の 107 〜 113 行目の以下のコード。

<script src="http://stats.wordpress.com/e-<?php echo gmdate('YW'); ?>.js" type="text/javascript"></script>
<script type="text/javascript">
st_go({<?php echo stats_array($a); ?>});
var load_cmc = function(){linktracker_init(<?php echo "{$a&#91;'blog'&#93;},{$a&#91;'post'&#93;},2"; ?>);};
if ( typeof addLoadEvent != 'undefined' ) addLoadEvent(load_cmc);
else load_cmc();
</script>

まず、外部 JavaScript http://stats.wordpress.com/e-<?php echo gmdate('YW'); ?>.js を読み込み、その後 st_go() 関数、linktracker_init() 関数を呼び出しています。

外部 JavaScript の読み込みが完了してからでないと st_go() 関数を呼び出すことはできないため、並列読み込みでは問題が生じます。
# JavaScript のロード完了まで待たないで継続処理を行われると処理不可能。

また、st_go() 関数の中では document.write() を使って <img> タグを書き出しているため、単純に DOM 操作で <script> タグを head 内にブチ込むだけでは、うまくいきません。

まずは、JavaScript のロード完了を待って処理を行う方法。
色々あるとは思いますが、今回は Yahoo! UI Library の Get Utility を使用して JavaScript の動的ロードを行います。
これを使うと以下のようにして、ロード成功時・失敗時のコールバック関数を指定することができます。

YAHOO.util.Get.script(
  [ 'http://example.com/javascript_1.js', 'http://example.com/javascript_2.js' ]
 ,{ onSuccess: function(){alert('OK!');}, onFailure: function(){alert('Fail!');} }
);

# 第一引数は、ロードしたい外部 JavaScript ファイルの URL
# 第二引数は、オプションでロード成功時・失敗時のコールバック関数等を指定できる

このライブラリを WordPress サイトに読み込むためには、以下のコードを stats.php の適当な場所に追加してください。

// YUI Get Utility の読み込み (管理画面以外の場合のみ)
function stats_scripts() {
	if ( !is_admin() ) {
		wp_register_script('yui-core', 'http://yui.yahooapis.com/2.5.2/build/yahoo/yahoo-min.js', false, '2.5.2');
		wp_register_script('yui-get',  'http://yui.yahooapis.com/2.5.2/build/get/get-min.js', array('yui-core'), '2.5.2');
		wp_enqueue_script('yui-get');
	}
}
add_action( 'wp_print_scripts', 'stats_scripts' );

これで準備完了。

次に stats.php の 107 〜 113 行目を以下のように修正すれば、外部 JavaScript を動的にロードした後、アクセス解析処理を行います。

<script type="text/javascript">
YAHOO.util.Get.script('http://stats.wordpress.com/e-<?php echo gmdate('YW'); ?>.js', { onSuccess: function(){
 // document.open(), document.close(), document.write() の退避
 var _open  = document.open;
 var _close = document.close;
 var _write = document.write;

 // document.open(), document.close(), document.write() の再定義
 document.open  = function(){};
 document.close = function(){};
 // div 要素を作成して body の最後に追加
 document.write = function(h){
  var d = document.createElement('div');
  d.innerHTML = h;
  var b = document.getElementsByTagName('body')[0];
  b.appendChild(d);
 };

 // stats 開始 (st_go() 関数内で document.write() が呼び出される)
 st_go({<?php echo stats_array($a); ?>});

 // 退避していた document.open(), document.close(), document.write() を元に戻す
 document.open = _open;
 document.close = _close;
 document.write = _write;

 // linktracker の初期化
 var load_cmc = function(){linktracker_init(<?php echo "{$a&#91;'blog'&#93;},{$a&#91;'post'&#93;},2"; ?>);};
 if ( typeof addLoadEvent != 'undefined' ) addLoadEvent(load_cmc);
 else load_cmc();
}});
</script>

以下、簡単な説明。

108 行目で JavaScript を動的にロードします。ロード成功後に実行されるスクリプトが 109 〜 136 行目。

126 行目で呼び出している st_go() 関数では document.write() を使って <img> タグを書き出しています。
このままだと head 内に document.write() で書き出されてしまうため、うまくありません。
と言うわけで 114 〜 123 行目で、document.open(), document.close(), document.write() をオーバーライド。
document.write() が呼び出されたら body の最後に <div> タグを作って、その中に書き込むように document.write() の処理を変更します。

これで JavaScript のロードを並列読み込み対応にした WordPress.com Stats プラグインの完成です。
この改造版の WordPress.com Stats プラグインは、昨日から当サイトで丸1日動かしてみてますが、正常にアクセスログを取得できているようなので大丈夫でしょう。


おまけ
Google Analytics を並列読み込み対応にするのは、もうちょっと簡単。以下のようにするだけです。

YAHOO.util.Get.script('http://www.google-analytics.com/urchin.js',{onSuccess:function(){
 _uacct = "Google Analytics の ID";
 urchinTracker();
}});

ロード対象の外部 JavaScript の中で document.write() を使ってなければ、Yahoo! UI Library の Get Utility は気軽に使えます。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください