我有一个使用jQuery加载XML文件的页面,然后我将其输出到页面。
最近我在输出中添加了一个排序功能,这会导致iPod Touch上的Safari挂起1分钟或2分钟(取决于我排序的字段数)以及在iPad上挂起不到1分钟。在Firefox 4.0.1上,相同的排序会在几秒钟内返回。
我担心这只是iOS的限制,但在我删除排序之前,也许可以进行优化。
在过滤器之前,XML中有357个项目。在过滤器之后,有199个项目按顺序排序。
var videoGames = $($.parseXML(videoGameXml)).find("game");
videoGames = videoGames.filter(function (a) {
return ($(this).attr('addOn') != "true" && $(this).find('own').text() == "yes");
});
videoGames.sort(function (a, b) {
var firstTitle = $(a).find('title').text().toLowerCase();
var secondTitle = $(b).find('title').text().toLowerCase();
var firstSystem = ($(a).find("console").text() + " " + $(a).find("version").text()).toLowerCase();
var secondSystem = ($(b).find("console").text() + " " + $(b).find("version").text()).toLowerCase();
if (firstSystem != secondSystem) {
if (firstSystem > secondSystem) {
return 1;
} else {
return -1;
}
} else {
if (firstTitle > secondTitle) {
return 1;
} else if (secondTitle < firstTitle) {
return -1;
}
}
return 0;
});
videoGames.each(function () {
// runs quickly, so removed
});
请注意,如果我将系统检查作为初始“优化”删除,将iPod Touch上的时间缩短一半,但仍然会导致上述1分钟的挂起。
那么,它是iOS设备限制,还是我可以优化我的排序?
答案 0 :(得分:2)
每次执行$(a)时,它都会执行一组非常复杂的操作,因此您最好对其进行缓存。此外,如果系统不同,您不需要标题。这个版本应该加快一点:
videoGames.sort(function (a, b) {
var first = $(a);
var second = $(b);
var firstSystem = (first.find("console").text() + " " + first.find("version").text()).toLowerCase();
var secondSystem = (second.find("console").text() + " " + second.find("version").text()).toLowerCase();
if (firstSystem != secondSystem) {
if (firstSystem > secondSystem) {
return 1;
} else {
return -1;
}
} else {
var firstTitle = first.find('title').text().toLowerCase();
var secondTitle = second.find('title').text().toLowerCase();
if (firstTitle > secondTitle) {
return 1;
} else if (secondTitle < firstTitle) {
return -1;
}
}
return 0;
});
您还可以缓存对象中的值
然后,而不是:
var firstSystem = (first.find("console").text() + " " + first.find("version").text()).toLowerCase();
执行:
var firstSystem = first.data('system');
if (!firstSystem) {
firstSystem = (first.find("console").text() + " " + first.find("version").text()).toLowerCase();
first.data('system') = firstSystem;
}
答案 1 :(得分:1)
您应该移动任何选择器调用:
var firstTitle = $(a).find('title').text().toLowerCase();
从比较器功能中输出。比较器功能应该是轻量级的。
使用children()
,next()
等等
扫描你设置一次并预先创建一个键数组,然后使用这些键对它进行排序。
比较器函数将被调用2n * ln(n)
次(取决于所使用的算法),其中n
是集合中的多个元素。因此,您的代码至少会执行两次相同的昂贵计算。