HTML5 では <script> タグに async という属性が加わってまして、これを指定しておくと src で指定された JavaScript ファイルの実行が非同期で行われます。(src 属性を指定しないと async は意味を持ちません。)
<script type="text/javascript" src="http://..." async="async">
</script>
ググってると async の値として async=”true” を指定しているページが多いようですが、W3C の HTML5 の定義(4.3.1 The script element と 2.4.2 Boolean attributes 参照)だと空の文字列か属性名そのものを指定しろってことになってますので、こっちが正しいです。(たぶんw)
If the attribute is present, its value must either be the empty string or a value that is an ASCII case-insensitive match for the attribute’s canonical name, with no leading or trailing whitespace.
2.4.2 Boolean attributes
まあ仕様書は読みにくいかもしれませんので、細かいことは w3schools.com の HTML 5 script Tag をご覧ください。こっちにはガッツリ値は “async” と書いてます。(HTML5 は XHTML じゃないので、面倒な話に関わりたくなかったら async 属性には値を指定しない方がいいと思いまつw)
いきなり話がだいぶずれちゃいましたが、とりあえず HTML5 では <script> タグに async 属性が追加され、これを使うと非同期で JavaScript を読み込むことができます。
※ただし IE6 は除く
Google Code Blog の Google Analytics Launches Asynchronous Tracking によると、Firefox 3.6 が始めて公式に async 属性をサポートしたブラウザらしいす。async 属性だけだと古いブラウザでは非同期になりませんので DOM を使って非同期になるようにコーディングしないといけません。幸い Google Code Blog に以下のような記述がありますので、古いブラウザでも同じ効果が得られます。
While it creates the same effect as adding a <script> element to the DOM, it officially tells browsers that this script can be loaded asynchronously.
Google Analytics Launches Asynchronous Tracking
ちょっと言い訳
誤解の無いよう先に書いときますと、時系列的には
AZlink/widget (embed) でほぼ完全な非同期コードが必要になった
↓
色々試す
↓
でけた\(^o^)/
↓
ブログに書こうそうしよう!
↓
ついでにちゃんと調べとくか←今ここ
という順になってまして、調べたついでに Google Analytics のこと書いちゃいましたが基本的に書きたかったことは Google Analytics の非同期コードとはあんま関係ないす。なら GA のこと書くなって感じすが、せっかく調べたんだからいーじゃんいーじゃんすげーじゃん(古w)。
とりまついでなんで GA のコード(ga.js)を見てみたらだいたい似たようなことしてましたが、要求事項が違うようでコードも微妙に違います。ということで GA とはあんま関係ないんだからねっ!
ということでやっと本題す。前置き長くなってどーもすいません。
setTimeout(function() {
var head = document.getElementsByTagName("head")[0] ||
document.documentElement;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://...';
head.appendChild(script);
}, 0);
<script>タグのasync属性を使わずに非同期でJavaScriptを読み込むには、setTimeout(, 0) の中で DOM オブジェクトを head 要素にひっつけるだけでいいす。(ちなみに ga.js では setTimeout してないのですが、これ入れないと JavaScript の読み込みでブロッキングが発生します。コードの実行はたぶん非同期なんでしょう。Firefox 3.5.7 で確認。)
head エレメントの取得は、document.getElementsByTagName(“head”)[0] || document.getElementsByTagName(“body”)[0] の方が手堅いかもしれません。(ga.js はこうなっとりました。でも GA は関係な(ry。)ただ、たしか head 要素が取れない時があるのは Opera だったと思うので、サポートするブラウザを IE5.5 以降とするなら上のコードで問題ないす。
ちなみに jQuery も head の取得に上と同じコードを使ってるので(っつーか上のコードの head を取得する部分は jQuery からパクったを参考にしたものです)、これが動かないブラウザだと jQuery も動かないので昨今の状況を鑑みると充分と思います。
なお、非同期で読み込んだ JavaScript で定義されてる関数を呼び出す場合、スクリプトの読み込みが終わるのを待ってから実行する必要があります。
例えばこういう JavaScript ファイルがあって、
// myfunc.js
function myfunc() {
alert('myfunc was loaded!');
}
それを非同期で読み込んですぐ myfunc を実行しようとしても、
setTimeout(function() {
var head = document.getElementsByTagName("head")[0] ||
document.documentElement;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'myfunc.js';
head.appendChild(script);
}, 0);
myfunc();
このタイミングでは myfunc は未定義です。JavaScript の実行キューは一本なので、setTimeout(, 0) が myfunc よりも先に実行されることはありません。未定義の関数を呼び出すとエラーになりますので、myfunc が定義されてから関数を実行するようにコードを書き換える必要があります。
リトライ&ゴーはarguments.calleeとsetTimeoutを使ってJavaScriptのリトライ処理を簡単に書く方法で説明した方法が簡単だと思います。で、完成形はこんな感じす。
setTimeout(function() {
var head = document.getElementsByTagName("head")[0] ||
document.documentElement;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'myfunc.js';
head.appendChild(script);
}, 0);
(function() {
if (typeof(myfunc) == 'undefined') {
setTimeout(arguments.callee, 15);
return;
}
myfunc();
})();

てな感じで前の記事から続いていたのでつ。
続く…