Загрузка содержимого HTML с помощью AJAX. Браузер не освобождает память - PullRequest
3 голосов
/ 31 августа 2011

У нас есть одностраничное приложение, которое загружает весь контент через ajax-вызовы в различные веб-сервисы.Начальная страница загружается только один раз, а затем, в зависимости от действий пользователя, различные контейнеры обновляются с помощью html-пакетов, которые мы представляем на сервере.

Теперь у нас есть проблема, которую мы обнаружили, когда приложение работает в течение длительного времени безповторный запуск.Браузер и компьютер начали работать медленно и менее быстро реагировать.Когда вы посмотрите на процесс в диспетчере задач, вы увидите, что он потребляет много памяти для процесса браузера.И процесс не освобождает память.

Я начал исследовать проблему, и при настройке примера приложения я обнаружил интересующий меня эффект.Приложение простое и состоит из метода веб-службы, страницы aspx и файла javascript.

Вот код.

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

Сегодня все наши звонки в веб-службу выполняются с помощью ajax framework asp.net scriptmanager.Но если вы запустите это тестовое приложение, вы можете увидеть различное поведение при получении данных с помощью jQuery ajax и asp.net ajax, по крайней мере, в IE9.Chrome кажется равным, но в IE9, когда вы выбираете данные с помощью jQuery, он не потребляет столько памяти, но в другом случае с asp.net ajax он растет и никогда не освобождает память.

У меня есть нескольковопрос здесь.Во-первых, в чем разница?Существуют ли потери производительности при использовании asp.net asp.net?И во-вторых, есть ли утечка памяти в моем коде JavaScript?Обычно это шаблон, который мы используем в приложении в упрощенном примере.Если что-то не так, мы должны это знать и исправлять.Является ли это потребление памяти вероятной причиной проблемы?У меня много памяти на компьютере разработчика, поэтому браузер может никогда не освободить память, потому что это не нужно?Может быть, это ложная тревога и проблема в другом.Обычная причина, по которой браузер не отвечает на запросы, - это высокая загрузка ЦП, но здесь это не так.

Цените любую помощь или новую точку зрения на проблему.Спасибо.

1 Ответ

2 голосов
/ 16 декабря 2011

Мне кажется, я наконец-то нашел ответ на этот вопрос.

IE9 не поддерживает функцию javascript eval (): http://support.microsoft.com/kb/2572253

Они рекомендуют некоторые обходные пути, одним из которых является использование JSON.parse при работе с десериализацией json.

Мы используем Ajax Control Toolkit Scriptmanager на нашей странице aspx. Но если вы исследуете, что он делает во внутреннем автоматически сгенерированном 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...