script defer の落とし穴

これ知らない人も多いんじゃないか。うろ覚えなんだけどさ。defer は確かに順序通りにグローバルな処理が実行されたはず。DOMContentLoaded も順序通り発生したはず。そしてスクリプトが並列で読み込まれる。悪いことなんかないように見える。でもまだ問題が起きる余地があったんだなあ。ここまで読んで気づく人は鋭いよ。A.js, B.js の順序で defer でスクリプトを読み込んで A.js のグローバル処理(Ag)、A.js の DOMContentLoaded(Ad)、B.js のグローバル処理(Bg)、B.js の DOMContentLoaded(Bd)、という 4 つの初期化処理があるとします。どういう順序で処理が発生して欲しいかって、Ag, Bg, Ad, Bd でしょう普通は。これは確かに順序通りにグローバル処理が実行されていて、順序通りに DOMContentLoaded が実行されています。ここまで書いて気づく人もまあまあ鋭いよ。でもダウンロード速度や js ファイルのキャッシュ状況次第で Ag, Ad, Bg, Bd の順序で実行されてしまうことがあるんだよ。これは確かに Ag, Bg と順序通りにグローバルな処理が実行されているし、Ad, Bd と DOMContentLoaded も順序通りに実行している。でも Ad と Bg の順序保証はしていないんだよ。ここなんだよ問題は。だから defer は使いづらい。そんな仕様なら defer を外してキャッシュに頼った方がマシじゃないか。

うろ覚えなので間違ったことを書いてるかもしれない。でもたぶんこんな感じだったよ。本当にはめられたと思った。詐欺みたいな仕様だよな。もしかしたら DOMContentLoaded では問題が起きないかも。jQuery ready 固有の問題かも。まあ気を付けた方がいいよ。