読者です 読者をやめる 読者になる 読者になる

以下斜め読んだ内容

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

Stoyan Stefanov「CSS/JSを先読しつつJSは実行させないでおく」

斜め読み

phpid.com2010.4.21のエントリ

Preload CSS/JavaScript without execution / Stoyan's phpied.com

  • プリロード系テクニックの最新版?
  • JSの高速ローディングをさらに細かくコントロールする、という趣旨
    • jsをロードしたい、キャッシュに保存したい。でも実行は遅延させて好きなタイミングで実行したい。これを実装
  • 辿りついたテクニックはシンプル
    • IE向けにはImageオブジェクト生成、それ以外はobject要素生成
    • 実行させたいときにオンザフライでscript要素を生成しDOMツリー追加
以下斜め読んだ内容
  • プリロードテクニックは色々あり前に調べた
    • script/link要素生成、iframe生成、XMLHttpRequest
    • 前調べたやり方は、iframeのロードや、プリロードされたcss/jsのパース/実行など、コストあり
    • プリロードされたjsの実行はjsエラーの温床になりやすい
  • ということでバージョンアップ
  • 結論
    • IE向けにはImage().srcを生成してロード
    • 他ブラウザ向けにはobject要素生成してロード
    • デモページ
//実装例
//ブラウザ判別はUA Detectionを使ってる
window.onload = function () {

    var i = 0,
        max = 0,
        o = null,

        // list of stuff to preload
        preload = [
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.png',
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.js',
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.css'
        ],
        isIE = navigator.appName.indexOf('Microsoft') === 0;

    for (i = 0, max = preload.length; i < max; i += 1) {

        if (isIE) {
            new Image().src = preload[i];
            continue;
        }
        o = document.createElement('object');
        o.data = preload[i];

        // IE stuff, otherwise 0x0 is OK
        //o.width = 1;
        //o.height = 1;
        //o.style.visibility = "hidden";
        //o.type = "text/plain"; // IE 
        o.width  = 0;
        o.height = 0;

        // only FF appends to the head
        // all others require body
        document.body.appendChild(o);
    }

};
//jsロード用のobject要素はbody要素の子要素としてDOMツリーへ追加
//実行したいときはscript要素を生成して追加しなおす
  • テストしたブラウザ
    • Fx3.6
    • Opera10
    • IE6-8
    • Chrome5
  • IE向けに処理を分けたのは・・・
    • object要素を使うやり方は、IE7/8では若干不具合
    • IE6では全く動かなかった
  • 結論に辿りつくまでの紆余曲折
    • うまくいかなかったテクニックが色々
    • Ben Cherryのアプローチ
    • script[type]に不正なMIMEタイプを指定するテクニック
      • 「type="text/javascript"」すべきところを「type="text/cache"」とか"text/html"とか指定するテクニック
      • 考案者不明。Ben Cherryのエントリのコメント欄、DejanPhilip Tellisが紹介してた
      • Fx3.6ではダメだった。
    • リンクプリフェッチ機能を使ってjsを読み込むアプローチ
      • link[rel="prefetch"]
      • Fx3.6以降サポートされた機能
      • Fxでも動かない