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エラーの温床になりやすい
- ということでバージョンアップ
- 結論
//実装例 //ブラウザ判別は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のアプローチ
- Adequately Good - Preloading JS and CSS as Print Stylesheets - by Ben Cherry
- オンザフライでlink要素生成、「media="print"」と指定して、ロード&キャッシュと実行を分離させる
- Chromeでうまく動かなかった
- ページ遷移するとキャッシュされたJSが実行されない。
- script[type]に不正なMIMEタイプを指定するテクニック
- 「type="text/javascript"」すべきところを「type="text/cache"」とか"text/html"とか指定するテクニック
- 考案者不明。Ben Cherryのエントリのコメント欄、Dejan、Philip Tellisが紹介してた
- Fx3.6ではダメだった。
- リンクプリフェッチ機能を使ってjsを読み込むアプローチ
- link[rel="prefetch"]
- Fx3.6以降サポートされた機能
- Fxでも動かない