日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2014年4月28日月曜日

javascript:優先度の低い要素を後で表示する遅延ロードを実装してみた

ブログで一つのページに様々なガジェットを張り付けていくと、どんどんページの表示速度が遅くなっていってしまいます。

ページの表示速度を早くしたい、、、でも要素も削れない。。。
そんな時にはせめて優先度の低い要素だけでも、遅れてデータの読み込みを行えるようにして、優先度の高い要素が先に表示されるようにしたい!

そんな(自分自身の)欲求にこたえるべく、要素の遅延読み込みを行う 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 />

&lt;b&gt;本来表示したい内容&lt;/b&gt<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 解釈されて収集されるのか検証していないのでわかりません。
このコードを使用される場合には、その点への留意が必要です。


関連情報

この機能を Blogger の HTML/JavaScriptガジェットに適用してみました。

優先度の低い要素を後で表示する遅延ロードをBloggerのガジェットに適用してみた(HTML/JavaScriptガジェット編)

http://upa-pc.blogspot.jp/2014/04/bloggerhtmljavascript.html





関連記事

関連記事を読み込み中...

同じラベルの記事を読み込み中...
Related Posts Plugin for WordPress, Blogger...