全ての中~大規模ゲームでは、コンパイル処理を最適化してブラウザを最大限柔軟にする、非同期スクリプトとして asm.js コードをコンパイルします。Gecko では、非同期コンパイルによって、ゲームのロード時に JavaScript エンジンがメインスレッド外で asm.js をコンパイルし、生成した機械語コードをキャッシュしてそれ以降のロード時にコンパイル不要となります(Firefox 28から)。違いを見るには、about:config
で javascript.options.parallel_parsing
を反転させてください。
非同期を動作させる
非同期のコンパイルは簡単です: JavaScript を書く時に、単に async
属性を使います:
<script async src="file.js"></script>
あるいは、スクリプトで同じことを行います:
var script = document.createElement('script');
script.src = "file.js";
document.body.appendChild(script);
(スクリプトによって生成されるスクリプトはデフォルトで非同期です。) デフォルトの HTML シェル Emscripten は、後者を生成します。
非同期とそうでない時?
スクリプトが非同期で *ない* 、よく似た状況 (仕様に定義されている通り) では次の通りです:
<script async>code</script>
および
var script = document.createElement('script');
script.innerHTML = "code";
document.body.appendChild(script);
両方とも 'インライン' スクリプトと考えられ、コンパイルされて、すぐに実行されます。
コードが JS 文字列内にあった場合はどうでしょう? eval
や innerHTML
(両方とも同期コンパイルを起動します)を使う代わりに、 オブジェクトURLと一緒の Blob を使います:
var blob = new Blob([codeString]);
var script = document.createElement('script');
var url = URL.createObjectURL(blob);
script.onload = script.onerror = function() { URL.revokeObjectURL(url); };
script.src = url;
document.body.appendChild(script);
innerHTML
ではなく src
をセットすると、スクリプトが非同期になります。