jquery - 使用ajax加载html内容。浏览器不释放内存

标签 jquery asp.net ajax browser memory-leaks

我们有一个单页应用程序,它通过 ajax 调用不同的 Web 服务来加载所有内容。起始页面仅加载一次,然后根据用户操作,使用我们在服务器上预渲染的 html 包更新不同的容器。

现在,当应用程序长时间运行而不重新启动时,我们发现了一个问题。浏览器和计算机开始变得缓慢且响应速度变慢。 当您在任务管理器中查看该进程时,您可以发现它作为浏览器进程消耗了大量内存。并且该进程没有释放内存。

我开始调查这个问题,在设置示例应用程序时,我发现了我想知道的效果。 该应用程序很简单,由一个 Web 服务方法、一个 aspx 页面和一个 JavaScript 文件组成。

这是代码。

网络服务:

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);
}

今天,我们对 Web 服务的所有调用都是通过 asp.net scriptmanager ajax 框架完成的。但是,如果运行此测试应用程序,您可以看到使用 jQuery ajax 和 asp.net ajax 获取数据之间存在一些不同的行为,至少在 IE9 中是这样。 Chrome 似乎是相同的,但在 IE9 中,当您使用 jQuery 获取数据时,它不会消耗那么多内存,但在使用 asp.net ajax 的其他情况下,它会增长并且永远不会释放内存。

我有几个问题。首先,有什么区别?使用 asp.net ajax 时是否存在性能损失?其次,我的 javascript 代码中是否存在内存泄漏?这通常是我们在整个应用程序的简化示例中使用的模式。如果有什么问题,我们需要知道并纠正。 这种内存消耗是否是问题的可能原因?我的开发人员计算机中有大量内存,因此浏览器可能永远不会释放内存,因为它不需要?也许这是误报,问题是别的。 浏览器似乎无响应的常见原因是 CPU 过高,但这里的情况并非如此。

感谢对问题的任何帮助或新观点。谢谢。

最佳答案

我想我终于找到了这个问题的答案。

IE9 不支持 javascript 函数 eval() : http://support.microsoft.com/kb/2572253

他们推荐了一些解决方法,其中之一是在处理 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);
    }
}

我相信这是问题的原因,我的选择是使用 jquery $.ajax 代替。

我希望这能帮助其他在 IE9 中遇到同样内存问题的人。

关于jquery - 使用ajax加载html内容。浏览器不释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7256437/

相关文章:

javascript - jQuery 和客户端 API 模式/框架

javascript - rails 5 : AJAX not triggering for save/load callbacks (PATCH/GET)

javascript - 在新标签页中打开 iFrame 链接?

javascript - 使用 JQuery 从 JSON 文件搜索/自动完成(只需要获取以给定字母开头的结果)

c# - 将日期时间转换为时间并显示在 GridView 的标签中

JavaScript - 将图像源更改为 gif?! ASP.NET

javascript - 如果使用jquery验证如何提交表单?

javascript - jQuery/JS - 计算元素内的元素数量

asp.net - 根据 index.cshtml 的 HTML 响应

javascript - 从服务器刷新并仅更新新元素