问题
你打算加载一个具有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('<','<')
.repalce('>','>');
}
$(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:
虽然简洁度降低了,但是访问者又不在乎,他们只重视加载速度。