ページの表示速度を早くしたい、、、でも要素も削れない。。。
そんな時にはせめて優先度の低い要素だけでも、遅れてデータの読み込みを行えるようにして、優先度の高い要素が先に表示されるようにしたい!
そんな(自分自身の)欲求にこたえるべく、要素の遅延読み込みを行う JavaScript を実装してみました。
コンセプトコード
コード全文
<html> <head> <title>test page</title> <script type="text/javascript"> <!-- var delay_load_objects = new Array(); // 遅延ロード用対象情報 /* *** !重要! *** 遅延ロードで挿入するデータが収められた要素内の内容には 少なくともひとつの < が含まれている必要があります。 エスケープ処理判定のため。 */ /* 遅延ロード用情報記録クラス target : 遅延ロードでデータを挿入する要素の id data : 遅延ロードで挿入するデータが収められた要素の id */ function CDelayLoad(target, data) { this.target = target; this.data = data; } /* 遅延ロード対象を設定 target : 遅延ロードでデータを挿入する要素の id data : 遅延ロードで挿入するデータが収められた要素の id */ function setDelayLoad(target, data) { delay_load_objects.push(new CDelayLoad(target, data)); } /* 遅延ロード実行 */ function runDelayLoad() { for (var i = 0; i < delay_load_objects.length; i++) { var delayLoadObj = delay_load_objects[i]; // 挿入先の要素を取得 var targetObj = document.getElementById(delayLoadObj.target); // データの要素を取得 var dataObj = document.getElementById(delayLoadObj.data); // 遅延ロード実行 // < がエスケープ処理されていなければ、unescape 処理不要 if (dataObj.innerHTML.indexOf('<') !== -1) { targetObj.innerHTML = dataObj.innerHTML; } else { targetObj.innerHTML = unescapeHTML(dataObj.innerHTML); } } /* エスケープされた文字列を元に戻す 参考文献:http://blog.tojiru.net/article/211339637.html */ function unescapeHTML(text) { var div = document.createElement("div"); div.innerHTML = text; if (div.innerText !== void 0) return div.innerText; // innerText が定義されていれば innerText を返す return div.textContent; // Firefox のように innerText がないブラウザ向け } } //--> </script> </head> <body onload="setTimeout('runDelayLoad();', 3000)"> <h1>delay Load TEST.</h1> <!-- 遅延ロードのための要素挿入 --> <script type="text/javascript"> <!-- var targetId = "delay_load_target_1"; var dataId = "delay_load_data_1"; document.write("<div id=\"" + targetId + "\">now loading...</div>"); // 遅延ロードとして登録 setDelayLoad(targetId, dataId); //--> </script> <!-- JavaScript が無効の場合、遅延ロードは行わない --> <noscript id="delay_load_data_1"> <b>本来表示したい内容</b><br /> <b>本来表示したい内容</b><br /> <img src="test.png" alt="test image" width="100" height="100" /><br /> </noscript> </body> </html>
概要
遅延読み込みを行いたい要素の内容を idを付けた<noscript>内に記載しておきます。<noscript>内に記載しておくのは、JavaScriptが無効になっているブラウザから読み込んだ場合に、表示したい情報が表示されないという事態を避けるためです。
遅延読み込みを行いたい要素の内容を記載した<noscript>の上に、遅延ロードを行うためのコードを記載します。
ここでは、遅延ロードの内容を挿入する要素の作成と、遅延ロードの{遅延ロードでデータを挿入する要素の id, 遅延ロードで挿入するデータが収められた要素の id} の登録を行っています。
最後に、ページが表示された後に遅延読み込みを行うために、<body>のonloadイベントに遅延読み込みのためのタイムアウトを設定しています。
今回は効果をわかりやすくするために、ページ表示後3秒経ったら、遅延読み込みを実施するようにしました。
結果
上記のコードを Chrome で表示してみると、次のような動きをします。
Chrome でページを読み込むと、遅延ロード指定部以外が表示される。
遅延ロード指定部は、「now loading...」となっている。
遅延ロード指定部の画像はこの時点では読み込まれていない。
↓
3秒経過すると遅延ロードが実行され、遅延ロード用データが表示される。
遅延ロードに指定した画像も遅延ロードの開始時間(ページ表示から3秒経過)から読み込みが開始されている。
以上で、遅延ロードが実行できることが確認できました。
なお、ブラウザの JavaScript 実行が無効の場合、遅延ロードは実施されず、<noscript>内に記載した遅延ロードで表示したかった内容がページ読み込み時に表示されます。
ブラウザの JavaScript 実行が無効の場合の表示
配布用コード
<head>内への貼り付け
JavaScript コードは、Closure Compiler(Googleが提供しているコード圧縮・最適化ツール)にて最適化しました。
<script type="text/javascript"> <!-- var delay_load_objects=[];function CDelayLoad(b,a){this.target=b;this.data=a}function setDelayLoad(b,a){delay_load_objects.push(new CDelayLoad(b,a))} function runDelayLoad(){for(var b=0;b<delay_load_objects.length;b++){var a=delay_load_objects[b],d=document.getElementById(a.target),a=document.getElementById(a.data);if(-1!==a.innerHTML.indexOf("<"))d.innerHTML=a.innerHTML;else{var a=a.innerHTML,c=document.createElement("div");c.innerHTML=a;a=void 0!==c.innerText?c.innerText:c.textContent;d.innerHTML=a}}}; //--> </script>
<body>タグへの設定
<body onload="setTimeout('runDelayLoad();', 3000)">
3000 の部分はページが表示されてから何ミリ秒経過後に遅延ロードを実施するのか指定してください。
遅延ロード対象箇所への設定
遅延ロードの対象箇所へ下記のコードを記載し、<noscrpt>タグ内に遅延ロードで表示する HTML を記載します。
ページ内に複数の遅延ロード対象が存在している場合、targetId と dataId の最後の番号をインクリメントして、各遅延ロード対象ごとにユニークな ID とします。
<!-- 遅延ロードのための要素挿入 --> <script type="text/javascript"> <!-- var targetId = "delay_load_target_1"; var dataId = "delay_load_data_1"; document.write("<div id=\"" + targetId + "\">now loading...</div>"); // 遅延ロードとして登録 setDelayLoad(targetId, dataId); //--> </script> <!-- JavaScript が無効の場合、遅延ロードは行わない --> <noscript id="delay_load_data_1"> <!-- 遅延ロードで表示する内容をここに記載 --> </noscript>
まとめ
今回は優先度の低い要素を後で表示する遅延ロードを実装してみました。優先度は低いけれど、絶対に表示したいもの(ページ下部のリンク集など)に適応してみてもよいかもしれません。
ただし、このコードによって遅延ロードとして設定した個所は検索エンジンのクローラによってちゃんと HTML 解釈されて収集されるのか検証していないのでわかりません。
このコードを使用される場合には、その点への留意が必要です。
コメントを投稿
コメント投稿機能について