我正在使用 Javascript 来解析一个包含大约 3,500 个元素的 XML 文件。我使用的是 jQuery“each”函数,但我可以使用任何形式的循环。
问题是浏览器在循环执行时冻结了几秒钟。在不使代码减慢太多的情况下停止冻结浏览器的最佳方法是什么?
$(xmlDoc).find("Object").each(function() {
//Processing here
});
我正在使用 Javascript 来解析一个包含大约 3,500 个元素的 XML 文件。我使用的是 jQuery“each”函数,但我可以使用任何形式的循环。
问题是浏览器在循环执行时冻结了几秒钟。在不使代码减慢太多的情况下停止冻结浏览器的最佳方法是什么?
$(xmlDoc).find("Object").each(function() {
//Processing here
});
我会放弃“each”函数,转而使用 for 循环,因为它更快。我还会使用“setTimeout”添加一些等待,但仅在需要时才这样做。您不想每次都等待 5 毫秒,因为处理 3500 条记录大约需要 17.5 秒。
下面是一个使用 for 循环的示例,该循环以 5 毫秒的间隔处理 100 条记录(您可以对其进行调整),这会产生 175 毫秒的开销。
var xmlElements = $(xmlDoc).find('Object');
var length = xmlElements.length;
var index = 0;
var process = function() {
for (; index < length; index++) {
var toProcess = xmlElements[index];
// Perform xml processing
if (index + 1 < length && index % 100 == 0) {
setTimeout(process, 5);
}
}
};
process();
我还将对 xml 处理的不同部分进行基准测试,以查看是否存在可以修复的瓶颈。您可以使用 firebug 的分析器在 firefox 中进行基准测试,并像这样写到控制台:
// start benchmark
var t = new Date();
// some xml processing
console.log("Time to process: " + new Date() - t + "ms");
希望这可以帮助。
在处理之间设置超时以防止循环周期吃掉所有浏览器资源。总的来说,处理和循环所有内容只需要几秒钟,对于 3,500 个元素来说并非不合理。
var xmlElements = $(xmlDoc).find('Object');
var processing = function() {
var element = xmlElements.shift();
//process element;
if (xmlElements.length > 0) {
setTimeout(processing, 5);
}
}
processing();
我会考虑将 3500 个元素从 xml 转换为 JSON 服务器端,或者甚至更好地将其上传到转换后的服务器,以便它从一开始就对 JS 来说是原生的。
这将最大限度地减少您的负载,并使文件大小也变得更小。
您可以 setTimeout() 的持续时间为零,它将根据需要产生
使用 Turboid 框架可以在不冻结浏览器的情况下进行长循环。有了它,您可以编写如下代码:
loop(function(){
// Do something...
}, number_of_iterations, number_of_milliseconds);
这篇 turboid.net 文章中的更多详细信息:Javascript 中的真实循环