Loading html content with ajax. Browser does not release memory
We have a single page application which loads all content through ajax calls to different web services. The start page is loaded only once and then depending on the user actions different containers are updated with html packages 开发者_C百科we prerender on the server.
Now we have a problem that we spotted when the application is running for long periods without restarting. The browser and computer started to get slow and less responsive. When you look at the process in task manager you can se that it consumes a lot of memory for being a browser process. And the process is not releasing the memory.
I started to investigate the problem and when setting up an example application I found an effect I am wondering about. The application is simple and consists of a web service method, an aspx page and a javascript file.
Here is the code.
Webservice:
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;
}
}
Aspx:
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="Scripts/JScript1.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService1.asmx"/>
</Services>
</asp:ScriptManager>
<input type="button" id="getDataJquery" value="Get data with jQuery"/>
<input type="button" id="getDataAspnet" value="Get data with asp.net"/>
<div id="container"></div>
</form>
</body>
Javascript:
$(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);
}
Today all our calls to the web service is done with asp.net scriptmanager ajax framework. But if you run this test application you can see some different behaviour between fetching data with jQuery ajax and asp.net ajax, at least in IE9. Chrome seems to be equal but in IE9, when you fetch data with jQuery it does not consumes that lot of memory but in the other case with asp.net ajax it grows and never releases the memory.
I have several question here. First, what is the difference? Are there perfomance losses when using asp.net ajax? And second is there a memory leak in my javascript code? This is usually the pattern we use throughout the application in a simplified example. If there is something wrong we need to know that and correct that. Is this memory consumption a likely reason to the problem? I have a lot of memory in my developer computer so the browser maybe never releasing the memory because it doesn't have to? Maybe this is false alarm and the problem is something else. The usual reason when a browser seems unresponsive is the CPU going high but this is not the case here.
Appreciate any help or new viewpoint on the problem. Thanks.
I think I finally have found the answer to this question.
IE9 doesn't support javascript function eval() : http://support.microsoft.com/kb/2572253
They recommend some workarounds, one of them is to use JSON.parse instead when dealing with json deserialization.
We use Ajax Control Toolkit Scriptmanager in our aspx page. But if you investigate what it does in its internal automatically generated js code you can see this code block:
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);
}
}
I believe this is the cause of the problem and my option will be to use jquery $.ajax instead.
I hope this will help others who experience the same memory problem in IE9.
精彩评论