◆ createElement で作った script タグの async プロパティは属性はなくても true
◆ 非同期だと読み込んだ順に実行
◆ 同期でも appendChild 直後に実行はされなくて非同期処理
  ◆ スクリプト読み込み後の実行順が appendChild 順になる

ネットでコード見てると なぜか async = false というのがありました
普通最初から非同期じゃないし false わざわざ指定って意味あるの?って思ったのですが MDN によると

スクリプトによって挿入された script は、IE および WebKit では非同期的に、Opera およびバージョン 4.0 より前の Firefox では同期的に実行します。Firefox 4.0 ではスクリプトが生成した script で async DOM プロパティの既定値が true であるため、デフォルトの動作が IE や WebKit の動作に一致します。スクリプトによって挿入された外部スクリプトをブラウザで挿入順に実行することを要求するには、document.createElement("script").async が true と評価される場合 (Firefox 4.0 など) に、順序を制御したい script で .async=false を設定します。

IE や Chrome などでは 非同期
昔の Firefox は同期
今の Firefox は Chrome などと一緒で非同期なようですね


同期的と聞くと HTML の script タグみたいにタグが追加された(読み込んだ)タイミングで実行してしまうように思うので
var sc = document.createElement("script")
sc.src = "sample.js" // x = 1
sc.async = false
document.head.appendChild(sc)
console.log(x)
これで sample.js の x が console.log で読めるの? って思ったのですがそんなことはなかったです

Uncaught ReferenceError: x is not defined(…)


じゃあ 何が同期なんだろうと 重いファイルと軽いファイルを使って調べてみました
var a = true
var s1 = document.createElement("script")
s1.src = "test-heavy.js"
s1.async = a

var s2 = document.createElement("script")
s2.src = "test-lite.js"
s2.async = a

document.head.appendChild(s1)
document.head.appendChild(s2)
s1 の方の test-heavy.js は数十MB の読み込みに時間かかるファイルで s2 の方の test-lite.js は数バイトの一瞬で読み込めるファイルです

a を true / false で切り替えて試していみます


async = false
script-async-sync

async = true
script-async-async


ファイルの読み込みはどっちもすぐにやっていますが 読み込んだ後のコードの実行が 非同期だと 先に読めた方からですが 同期だと appendChild した順になっています

MDN の引用した部分 後半をよく読むとそんな感じのことが書いていました



それと スクリプト上で document.createElement("script") したものは Firefox だけでなく Chrome でも async は true になっていました
HTML タグの属性には async がついていないので気づかなかったですが デフォルトは true なんですね
紛らわしいので 属性の async もつけておいてくれたらいいのに