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でも動かない