Javascript 加速Ajax在DOM操作中的成功
我在我的页面上使用了一个AJAX调用,它返回表行,成功后将它们添加到页面中的表中。以下是当前使用的代码:Javascript 加速Ajax在DOM操作中的成功,javascript,jquery,ajax,Javascript,Jquery,Ajax,我在我的页面上使用了一个AJAX调用,它返回表行,成功后将它们添加到页面中的表中。以下是当前使用的代码: function GetDPRecords(Perso) { //alert(Perso); $Records = $('#DPRecords'); //alert($PersoFileName.val()+" | "+$ProcFromDate.val()+" | "+$ProcToDate.val()); $.ajax({
function GetDPRecords(Perso) {
//alert(Perso);
$Records = $('#DPRecords');
//alert($PersoFileName.val()+" | "+$ProcFromDate.val()+" | "+$ProcToDate.val());
$.ajax({
type: "GET",
url: "SelectDPRecords.jsp",
data: $('form#Search_Form').serialize() + "&Personalized=" + Perso,
beforeSend: function () {
$Records.find("tr:gt(0)").remove();
$("<tr><td colspan='4'><h3 style='margin: 4px 10px'> Loading... </h3></td></tr>").hide().appendTo($Records).show(400);
},
success: function (data) {
$Records.find("tr:gt(0)").remove();
$(data).hide().appendTo($Records).show(400);
}
});
}
函数GetDPRecords(Perso){
//警惕(个人);
$Records=$('DPRecords');
//警报($PersoFileName.val()+“|”+$ProcFromDate.val()+“|”+$ProcToDate.val());
$.ajax({
键入:“获取”,
url:“SelectDPRecords.jsp”,
数据:$('form#Search_form')。serialize()+“&Personalized=“+Perso,
beforeSend:函数(){
$Records.find(“tr:gt(0)”).remove();
$(“加载…”).hide().appendTo($Records).show(400);
},
成功:功能(数据){
$Records.find(“tr:gt(0)”).remove();
$(数据).hide().appendTo($Records).show(400);
}
});
}
问题是,我有时希望返回大量行(1000-5000)。我对返回的4000行数据进行了测试,结果导致浏览器在大约20秒内没有响应
有没有办法优化代码并减少加载时间?一种可能的解决方案是使用分页系统:不返回1000-5000行,而是将结果分成若干页,每个页包含50个结果,一次只返回一页。然后,您将给用户按钮,以便在表的顶部/底部加载其他页面
有关我所说内容的示例,请参见。它使用图片而不是行,但这是相同的基本概念。只需添加@aj_r的建议,如果您不想再次点击服务器检索下一个范围的数据,则可以将结果存储到javascript变量(JSON对象数组)然后在本地使用分页。我最近在jqGrid中使用巨大的数据网格时遇到了同样的问题,我找到了一个棘手的解决方案,结果证明效果非常好 问题是您不能一次呈现所有这些数据——这太多了,特别是考虑到DOM操作有多慢。所以你需要排队。您可以使用
setTimeout()
或setInterval()
将这些数据分割成块并依次呈现,但这些数据在性能方面也没有很好的声誉
我最终使用了ReueStationFrame,将我的海量数据分割成若干片段,并在动画帧可用时进行渲染。因此,您需要从polyfill开始,以确保您将要执行的操作将真正起作用,我使用的是Paul irish的一个很棒的操作:
这里有一个令人讨厌的问题:
以下是JS:
var dataRows = 5000; // enter ammount of returned rows
var chunkSize = 200; // define single chunk size, optimize for best performance bu trying different values, if your DOM manipulation is heavy use less, if its lightweight you can use more, use 1 to see in slowmo how it works
// We are simulating big returned object here
var data = {}
for (var i = 0; i < dataRows; i++) {
data[i] = {
'id': i,
'name': 'I am data for row ' + i
};
}
// shim layer with setTimeout fallback
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function renderRecords(data) {
var dataLength = Object.keys(data).length;
var i = 0;
function renderInQueue() {
console.time('Rendering in queue');
for (t = 0; t < chunkSize; t++) {
if (i < dataLength) {
var row = '<tr><td>' + data[i].id +
'</td><td>' + data[i].name + '</td></tr>'
$('table').append(row);
}
i++;
}
if (i < dataLength) {
requestAnimationFrame(renderInQueue);
} else {
console.log('Done rendering');
console.timeEnd('Rendering in queue');
}
}
renderInQueue();
}
// run the script of rendering
renderRecords(data);
var dataRows=5000;//输入返回行的数量
var chunkSize=200;//定义单块大小,通过尝试不同的值来优化以获得最佳性能,如果您的DOM操作很重,使用较少,如果它很轻,您可以使用更多,请使用1在slowmo中查看它是如何工作的
//我们在这里模拟返回的大对象
变量数据={}
对于(变量i=0;i
我提供了一个简单的性能基准,让您在console中了解整个渲染过程需要多少时间。使用chunkSize
查看它是如何变化的,并尝试找到一个最适合您需要的值,即在不增加浏览器负载的情况下为您提供适当的渲染时间
一次渲染的次数越多,渲染速度就越快,但处理每次渲染迭代都需要更多的资源。您是否尝试过
$Records.empty()
或$Records.find('tbody').empty()
?$(data.hide())
似乎有些奇怪。您是否考虑过返回JSON,以便JavaScript可以根据需要管理大量数据集,而不是大量的标记,并希望浏览器能够有效地解析它?我想知道$(日期)的行为如何。hide()您是否可以将该部分替换为$Records.append(数据)并查看它提供了什么?20秒对于标记插入来说似乎很长,在您编写的内容中可能有一个循环。该循环位于处理响应的servlet中。但那部分不应该挂在浏览器上,对吗?(它是‘A’JAX)——@Sukima你能帮我了解一下JSON有什么帮助吗。。由于DOM操作仍然需要时间,因此它会从JSON->HTML添加更多的解析/转换?我确实想到了分页。。但必须看看它如何与我当前的响应servlet相适应(需要在那里进行更改?或者只在客户端代码部分进行更改),这似乎是一个更受欢迎的选项。是否可以将我的响应改为DOM而不是JSON?谢谢bro,但是IE8不能使用requestAnimationFrame
,不幸的是,IE8需要支持。你能告诉我没有它怎么办吗(简单的setInterval()/setTimeOut()
)多亏了polyfill,这在IE8中也会起作用,它会退回到win吗