以下斜め読んだ内容

pseudo translation of useful posts, book reviews, remarks,etc. twitter: feeddict

Nicholas C. Zakas「Loading JavaScript without blocking」

NCZOnline、2009.6.23のエントリ

Loading JavaScript without blocking

Steve Soudersの同名エントリLoading Scripts Without Blockingへのリプライ記事。
Soudersのエントリでは、他のコンポーネントのロードをブロックしないjsロードのためのテクニックが、XHR使用2つ、iframe使用2つ、DOM使用1つ、script[defer]使用1の5つ紹介されてるが、各テクニックの実装サンプルは割愛されてる(書籍では、サンプルコード載ってる)。
Zakasは「DOM使用」タイプ(オンザフライでscript要素生成しjsロードするテクニック)について、3本立ての補足

  • サンプルコード
  • プラスアルファでコールバック指定したい場合のサンプルコード
  • YUI3も実装済なことを例に即して
以下斜め読んだ内容
  • Soudersのエントリで紹介されてたオンザフライでscript要素生成しjsロードするテクニック
  • サンプルコード内から書いた
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";
document.body.appendChild(script);
  • 機能追加:jsロード終わったらコールバック指定できるようにしたい
  • IE以外はscript要素にloadイベントにセットすればいい、カンタン
  • IE対策
    • (script要素では)loadイベントない
    • 代わりにreadyStateプロパティとreadystatechangeイベント(readyStateの値の変化をキャッチする)で実装
  • readyStateプロパティはMSDNに書かれてることと実情が違うから注意
  • 「仕様では」readyStateプロパティが取りうる値は5つ
    • uninitialized
      • デフォルト
    • loading
      • DL開始
    • loaded
      • DL完了
    • interactive
      • データはアクセスできるが十分にアクセスできない
    • complete
      • データにアクセスできる状態になってる
  • readyStateプロパティの実際の動きで問題になる点
    • どんどん状態変化していってcompleteになるはずなのに、ならない場合あり
    • loadedでストップする場合がある。
    • なので、loadedかcompleteになったらコールバック実行という風に実装すればよい
//Internet Explorer only
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";
script.onreadystatechange = function(){
    if (script.readyState == "loaded" ||
            script.readyState == "complete"){
        script.onreadystatechange = null;
        alert("Script is ready!");
    }
};
document.body.appendChild(script);
  • あとはクロスブラウザ対応用にIE以外とIE用をラップする関数にするだけ
  • 話は戻って、オンザフライでscript要素生成しjsロードするテクニックはYUI3でも使ってるテクニック
  • 他のコンポーネントをブロックしないでjsロードしたいとき、YUI使ってるひとはすぐできるよ
YUI().use("dom", function(Y){
    Y.DOM.addClass(document.body, "active");
});
  • 上のYUI依存のコードがやってること
感想

loadedでストップしたりcompleteでストップしたりする理由が分からなかったけど、「外部JavaScriptの動的ロード - 0xFF」読んだ。

  • キャッシュされてないjsは、loaded
  • キャッシュされてるjsは、complete

と理解した。