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

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

2014年5月30日金曜日

Blogger:投稿一覧をdocument.writelnではなく、要素のinnerHTMLに挿入することでページの表示を軽くする

イントロダクション

記事「Blogger:投稿一覧を作成する-10 件ごとにラインを引く」にて作成した記事一覧作成用の JavaScript をしばらく使ってみましたが、ページを表示した直後に下にスクロールしようとすると、スクロールした部分が空白のまま1~2秒程度固まる現象が発生しており、少し重たいように感じました。

現時点の記事総数は 331 件であり、だいぶ記事の数が増えてきたので、記事一覧を作成する処理もだいぶ負荷がかかっているのかなと想像しました。



そこで、現時点でどの程度処理に時間がかかっているのか測定してみることにしました。
測定は以下のコードで測定対象コードを挟むことで測定を実施しました。

    // 処理時間計測
    var start_time = new Date();

    /* --- 測定対象コード --- */

    // 処理時間計測
    var end_time = new Date();
    var process_span = end_time - start_time;    // 処理時間(ms)

    document.writeln("<br />記事一覧の作成にかかった時間は " + process_span + " ms です。<br />");


その結果は次のようになりました。

1回目:記事一覧の作成にかかった時間は 832 ms です。
2回目:記事一覧の作成にかかった時間は 638 ms です。
3回目:記事一覧の作成にかかった時間は 748 ms です。

この 3 回分の測定結果からすると、記事一覧の作成には平均 0.7 秒ほどかかっていることがわかりました。


現在のコードでは、document.writeln を使い記事一覧の HTML を出力しています。
かつ、document.writeln を都度何度も呼び出しています。

そのため、その処理が遅さの原因ではないかと考え、document.writelnではなく、要素の innerHTML に記事一覧の HTML をまとめて出力するように修正してみました。


コード

以下のコードを Blogger のページに埋め込みました。

<div id="post-list-container">
記事一覧生成中...
</div>
<div id="post-list-gen-time">
</div>
<script type="text/javascript">
<!--
function loadtoc(data) {

    // 処理時間計測
    var start_time = new Date();


    var html = "";
    
    html += "<ol>";
    for (var i = 0; i < data.feed.entry.length; i++) {
        
        // リンク先の探索
        var href = "javascript:void(0);";
        for (var j = 0; j < data.feed.entry[i].link.length; j++) {
            if (data.feed.entry[i].link[j].title == data.feed.entry[i].title.$t) {
                href = data.feed.entry[i].link[j].href;
            }
        }

        // ラベル一覧作成
        var labels = "";
        if (data.feed.entry[i].category) {
            for (var j = 0; j < data.feed.entry[i].category.length; j++) {
                var label = data.feed.entry[i].category[j].term;
                var labelLink = location.protocol + "//" + location.host + "/" + label;

                labels += "<span><a href=\"" + labelLink + "\">" + label + "</a><span>";
                if (j < data.feed.entry[i].category.length - 1) {
                    labels += ",";
                }
            }
        }

        html += "<li><a href=\"" + href + "\" title=\"" +
            fixForAttributeTitle(escapeForAttributeText(data.feed.entry[i].summary.$t)) + "\">" +
            escapeHTML(data.feed.entry[i].title.$t) + "</a><br />ラベル:" + labels + "<br /><br /></li>";


        // 記事のまとまりごとにラインを引く
        if ((i % 10) == 9) {
            html += "<hr />";
        }

    }
    html += "</ol>";


    var obj_output = document.getElementById("post-list-container");
    obj_output.innerHTML = html;


    // 処理時間計測
    var end_time = new Date();
    var process_span = end_time - start_time;    // 処理時間(ms)

    document.getElementById("post-list-gen-time").innerHTML = "<br />記事一覧の作成にかかった時間は " + process_span + " ms です。<br />";
    

    // テキストをエスケープ処理する
    function escapeHTML(html) {

        var div = document.createElement("div");
        if (div.innerText !== void 0) div.innerText = html;          // innerText が定義されていれば innerText へ設定
        else div.textContent = html;                                 // Firefox のように innerText がないブラウザ向け

        return div.innerHTML;
    }

    // 属性用にテキストをエスケープ処理する
    function escapeForAttributeText(html) {

        // " をエスケープ
        html = html.replace(/\&/g, "&amp;");

        html = html.replace(/\</g, "&lt;");
        html = html.replace(/\>/g, "&gt;");
        html = html.replace(/\"/g, "&quot;");
        html = html.replace(/\'/g, "&apos;");
        return html;
    }

    // 属性の title 用にテキストを整理する
    function fixForAttributeTitle(text) {

        text = text.replace(/(\r\n){2,}/g, "$1$1");
        text = text.replace(/(\r){2,}/g, "$1$1");
        text = text.replace(/(\n){2,}/g, "$1$1");

        return text;
    }
}

//-->
</script>
<script src="http://upa-pc.blogspot.com/feeds/posts/summary?alt=json-in-script&callback=loadtoc&max-results=500&redirect=false" type="text/javascript"></script>

以前のコードで document.writeln を使用していた箇所すべてを、バッファのテキストに追加していく処理に置き換えました。

最後に、要素の innerHTML に作成したバッファのテキストを代入して、記事一覧を表示するようにしています。

結果

上記のコードを実行した結果は、次のようになりました。

1回目:記事一覧の作成にかかった時間は 53 ms です。
2回目:記事一覧の作成にかかった時間は 62 ms です。
3回目:記事一覧の作成にかかった時間は 53 ms です。


記事一覧の生成に平均 0.06 秒かかっていることがわかりました。

document.writeln を使用したコードでは、平均 0.7 秒ほどかかっていたことから、実行時間は1/10以下に短縮できました。


ただし、相変わらずページを表示した直後に下にスクロールしようとすると、スクロールした部分が空白のまま1~2秒程度固まる現象が発生しており、本件の対処ではその問題を解決することはできませんでした。

他のページでは、その現象は発生していないようなので、単純にページ自体が長すぎることで発生しているようです。
→ 試しに記事一覧で表示する記事の件数を 10 件に制限して表示させたところ、上記の減少は発生しませんでした。つまり、ページに数百件の記事一覧を一度に表示するのは重すぎるようです。

その対策は今後考えることにします。





関連記事

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

同じラベルの記事を読み込み中...