編寫更快地載入表格

戰五渣發表於2018-04-22

問題

你打算載入一個具有1000個姓名個地址的json資料物件,並用jq以這些資料建立一個表格。在IE7中建立這個表格花費
5~10秒,這還不包括下載時間。
json資料格式如下:

{
    "name":{
        {
            "first":"alice",
            "last":"tom",
            "street":"221B",
            "city":"beijing",
            "state":"VA",
            "zip":"15445"
        },
        //重複1000個姓名
    }
}

js程式碼如下

function esc(){
    return text
        .replace(`&`,`&`)
        .replace(`<`,`&lt;`)
        .repalce(`>`,`&gt;`);
}
$(document).ready(function () {
        function fillTable(names) {
            $.each(names,function () {
                $(`<tr>`)
                    .append($(`<td>`).addClass(`name`).html(
                        esc(this.first) + `` + esc(this.last)
                    ))
                    .append($(`<td>`).addClass(`address`).html(
                        esc(this.street) + `<br/>` +
                        esc(this.city) + `,` +
                        esc(this.state) + `` + esc(this.zip)    
                    ))
                    .appendTo(`#nameTable`);
            });
        }
        $getJSON(`names/names-1000.json`,function (json) {
            fillTable(json.names);
        });
    });

heml程式碼

<table id="nameTbale">
</table>

看似沒毛病,但它執行得太慢了。

解決方案:

組合多種優化方案:

  • 插入一個<table>或者<tbody>代替多個<tr>元素。
  • 使用.innerHTML或.html()代替DOM操作。
  • 用a[++i]和.join()構建陣列,代替字串連線。
  • 使用基本的for迴圈代替$.each.
  • 減少名稱查詢。

優化的結果程式碼如下(使用esc()函式):

$(document).ready(function () {
        function fillTable(names) {
            //用區域性函式名稱減少名稱查詢
            var e = esc;
            //
            var html = [], h = -1;
            html[++h] = `<table id="nameTable">`;
            html[++h] = `<tbody>`;
            for (var name, i = -1; name = names[++i];) {
                html[++h] = `<tr><td class="name">`;
                html[++h] = e(name.first);
                html[++h] = ``;
                html[++h] = e(name.last);
                html[++h] = `<td><td class="address">`;
                html[++h] = e(name.street);
                html[++h] = `<br/>`;
                html[++h] = e(name.street);
                html[++h] = ``;
                html[++h] = e(name.state);
                html[++h] = ``;
                html[++h] = e(name.zip);
                html[++h] = `</td></tr>`;
            }
            html[++h] = `</tbody>`;
            html[++h] = `</table>`;
            
            $(`#container`)[0].innerHTML=html.join(``);
        }
        $.getJSON(`name/names-1000.json`,function (json) {
                fillTable(json.names);
            });
        
    });

html程式碼

<div id="container">
</div>

在IE中的一個測試系統上,新程式碼僅僅執行0.2秒,而原來的程式碼執行了7秒。快34倍!
(資料來源《jQuery Cookbook》)
ps:

雖然簡潔度降低了,但是訪問者又不在乎,他們只重視載入速度。

相關文章