Jquery 使用ajax加载html内容。浏览器不会释放内存
我们有一个单页应用程序,它通过对不同web服务的ajax调用加载所有内容。起始页只加载一次,然后根据用户操作,使用我们在服务器上预呈现的html包更新不同的容器 现在,当应用程序长时间运行而不重新启动时,我们发现了一个问题。浏览器和计算机开始变慢,响应速度变慢。 在任务管理器中查看该进程时,可以发现它作为浏览器进程会消耗大量内存。这个过程并没有释放内存 我开始研究这个问题,在设置一个示例应用程序时,我发现了一个我想知道的效果。 该应用程序很简单,由一个web服务方法、一个aspx页面和一个javascript文件组成 这是代码 网络服务:Jquery 使用ajax加载html内容。浏览器不会释放内存,jquery,asp.net,ajax,browser,memory-leaks,Jquery,Asp.net,Ajax,Browser,Memory Leaks,我们有一个单页应用程序,它通过对不同web服务的ajax调用加载所有内容。起始页只加载一次,然后根据用户操作,使用我们在服务器上预呈现的html包更新不同的容器 现在,当应用程序长时间运行而不重新启动时,我们发现了一个问题。浏览器和计算机开始变慢,响应速度变慢。 在任务管理器中查看该进程时,可以发现它作为浏览器进程会消耗大量内存。这个过程并没有释放内存 我开始研究这个问题,在设置一个示例应用程序时,我发现了一个我想知道的效果。 该应用程序很简单,由一个web服务方法、一个aspx页面和一个jav
public class WebService1 : WebService
{
[WebMethod]
public string GetData()
{
var returnValue = "";
var webRequest = WebRequest.Create("http://www.w3schools.com/");
var webResponse = webRequest.GetResponse();
var responseStream = webResponse.GetResponseStream();
if (responseStream != null)
{
using(var streamReader = new StreamReader(responseStream))
{
returnValue = streamReader.ReadToEnd();
var startBody = returnValue.IndexOf("<body>") + "<body>".Length;
var endBody = returnValue.IndexOf("</body>");
returnValue = returnValue.Substring(startBody, endBody - startBody);
}
}
return returnValue;
}
}
今天,我们对web服务的所有调用都是使用asp.net scriptmanager ajax框架完成的。但是,如果您运行这个测试应用程序,您可以看到使用jQueryAjax和asp.NETAjax获取数据之间的一些不同行为,至少在IE9中是这样。Chrome似乎是平等的,但在IE9中,当您使用jQuery获取数据时,它不会消耗那么多内存,但在另一种情况下,使用asp.net ajax时,它会增长,并且永远不会释放内存
我这里有几个问题。首先,有什么区别?使用asp.net ajax时是否存在性能损失?第二,我的javascript代码中是否存在内存泄漏?在一个简化的示例中,这通常是我们在整个应用程序中使用的模式。如果有什么问题,我们需要知道并纠正它。
这种内存消耗可能是问题的原因吗?我的开发人员计算机中有很多内存,所以浏览器可能永远不会释放内存,因为它不需要释放内存?也许这是虚惊一场,而问题是别的。
当浏览器看起来没有响应时,通常的原因是CPU过高,但这里的情况并非如此
感谢对这个问题的任何帮助或新观点。谢谢。我想我终于找到了这个问题的答案 IE9不支持javascript函数eval(): 他们推荐一些解决方法,其中之一是在处理JSON反序列化时使用JSON.parse 我们在aspx页面中使用Ajax控制工具包Scriptmanager。 但是,如果您调查它在内部自动生成的js代码中做了什么,您可以看到以下代码块:
Sys.Serialization.JavaScriptSerializer.deserialize = function Sys$Serialization$JavaScriptSerializer$deserialize(data, secure) {
/// <summary locid="M:J#Sys.Serialization.JavaScriptSerializer.deserialize" />
/// <param name="data" type="String"></param>
/// <param name="secure" type="Boolean" optional="true"></param>
/// <returns></returns>
var e = Function._validateParams(arguments, [
{name: "data", type: String},
{name: "secure", type: Boolean, optional: true}
]);
if (e) throw e;
if (data.length === 0) throw Error.argument('data', Sys.Res.cannotDeserializeEmptyString);
try {
var exp = data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx, "$1new Date($2)");
if (secure && Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(
exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx, ''))) throw null;
return eval('(' + exp + ')');
}
catch (e) {
throw Error.argument('data', Sys.Res.cannotDeserializeInvalidJson);
}
}
Sys.Serialization.JavaScriptSerializer.deserialize=函数Sys$Serialization$JavaScriptSerializer$deserialize(数据,安全){
///
///
///
///
var e=函数。\u验证图(参数[
{name:“data”,类型:String},
{name:“secure”,类型:Boolean,可选:true}
]);
如果(e)抛出e;
if(data.length==0)抛出Error.argument('data',Sys.Res.cannotDeserializeEmptyString);
试试{
var exp=data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx,“$1新日期($2)”);
if(secure&&Sys.Serialization.JavaScriptSerializer.\u jsonRegEx.test(
exp.replace(Sys.Serialization.JavaScriptSerializer.\u jsonStringRegEx',))抛出null;
返回值(“(“+exp+”)”);
}
捕获(e){
抛出错误。参数('data',Sys.Res.cannotDeserializeInvalidJson);
}
}
我相信这就是问题的原因,我的选择是使用jquery$.ajax
我希望这能帮助那些在IE9中遇到同样内存问题的人。你在不同的浏览器中测试过吗?您是否看到它们中的许多内存使用量增加了?如果您可以将其缩小到单个浏览器,则可能是浏览器内存泄漏,而不是与您的应用程序有关。附带说明:您可能希望使用setInterval而不是setTimeout,因为您似乎希望每2秒重复从服务器获取数据。此外,您可能希望将内容清除代码移动到ajax响应处理程序中,这样用户就不会在请求和响应之间看到空内容。最后,您需要小心单击处理程序中的超时代码。如果用户在T 0毫秒时单击,然后在T 50毫秒时再次单击,则您将通过设置超时在T 2000毫秒和T 2050毫秒时重新加载内容。您可能想清除超时。这只是一个测试应用程序。我所说的“这通常是我们在整个应用程序中使用的模式”是指我们调用Web服务的方式。在测试应用程序中,这里的目的只是单击一次其中一个按钮来创建一个循环。我还从html中清除容器,以查看实际发生的事情。我们在应用程序中不这样做。是的,谷歌chrome和ie9都存在这个问题。
$(document).ready(function () {
$('#getDataJquery').click(function () {
getDataWithJQuery();
setTimeout(function () {
$('#container').html('');
$('#getDataJquery').trigger('click');
}, 2000);
});
$('#getDataAspnet').click(function () {
getDataWithAspnet();
setTimeout(function () {
$('#container').html('');
$('#getDataAspnet').trigger('click');
}, 2000);
});
});
function getDataWithJQuery() {
$.ajax({
url: 'WebService1.asmx/GetData',
type: 'POST',
dataType: 'json',
success: jQueryResponse,
contentType: 'application/json'
}
);
}
function getDataWithAspnet() {
AjaxJqueryVsAspNet.WebService1.GetData(aspnetResponse);
}
function jQueryResponse(response) {
loadHtml(response.d);
}
function aspnetResponse(response) {
loadHtml(response);
}
function loadHtml(html) {
$('#container').html(html);
}
Sys.Serialization.JavaScriptSerializer.deserialize = function Sys$Serialization$JavaScriptSerializer$deserialize(data, secure) {
/// <summary locid="M:J#Sys.Serialization.JavaScriptSerializer.deserialize" />
/// <param name="data" type="String"></param>
/// <param name="secure" type="Boolean" optional="true"></param>
/// <returns></returns>
var e = Function._validateParams(arguments, [
{name: "data", type: String},
{name: "secure", type: Boolean, optional: true}
]);
if (e) throw e;
if (data.length === 0) throw Error.argument('data', Sys.Res.cannotDeserializeEmptyString);
try {
var exp = data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx, "$1new Date($2)");
if (secure && Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(
exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx, ''))) throw null;
return eval('(' + exp + ')');
}
catch (e) {
throw Error.argument('data', Sys.Res.cannotDeserializeInvalidJson);
}
}