Использование javascript setInvertal увеличивает потребление памяти процессором

Я занимаюсь разработкой веб-приложения.NET, где мне нужно выполнить ajax-запросы с помощью функции javascript setInterval(), чтобы обновить информацию о некоторых страницах.

С каждым ajax-запросом я получаю xml-ответ размером около 68 КБ, который мне удается визуально изменить в html через jQuery. Я установил интервал в 2000 миллисекунд, но мне хотелось бы, или, скорее, мне нужно уменьшить его до 1000 мс.

К сожалению, с каждым запросом потребление памяти ЦП увеличивается, и это провоцирует, что браузер блокируется, и пользователь не может использовать его, пока он не перезагрузит страницу. Я проверил это в Firefox, Internet Explorer и Chrome, но результат всегда одинаков. Если я не сделаю setInvertal(), проблема исчезнет.

Кроме того, я проверял область действия всех моих переменных javascript, но я не нашел ничего неправильного, и я полагаю, что Javascript имеет эффективный сборщик мусора для их очистки.

Я надеюсь, что я объяснил ясно, вопрос. У кого-то есть идея решить это?

Модифицировано: я использую фреймворк jQuery. Мой код:

var tim;
$(document).ready(function () {
  tim = window.setInterval("refresh()", 2000);
});

function refresh() {
   $.post("procedures.aspx", $("#formID").serializeArray(), function (data) {
     if (data != ""){
       var xml = $.parseXML(data);

       ... (read and process xml to do changes in the html)

     }
   }
}

2 ответа

Решение

Вы не опубликовали ни одного фрагмента кода для проверки, поэтому мой ответ основан на ошибке, которая обычно допускается при создании таких "опрашивающих" функций. Я также предполагаю, что вы делаете вещи вручную, без использования таких фреймворков, как jQuery или MooTools.

Скорее всего, ваша проблема вызвана созданием нового объекта XMLHttpRequest при каждом вызове опроса, а не созданием одного такого экземпляра вне setInterval, а также открытием и использованием этого снова и снова.

По сути, вы можете писать свой код так:

var pollInterval = setInterval(function() {
    var xhr = new XMLHttpRequest(); //ouch, this hurts!
    xhr.open('GET', 'url', true);
    xhr.send();
    //etc.
}, 2000);

Если это так, просто переместите создание XMLHttpRequestObject из цикла опроса, чтобы убедиться, что вы снова и снова используете один и тот же объект, тем самым предотвращая утечку памяти в некотором роде (если можно так назвать).

var xhr = new XMLHttpRequest(); //now we can re-use this!
var pollInterval = setInterval(function() {
    xhr.open('GET', 'url', true);
    xhr.send();
    //etc.
}, 2000);


Опять же, вы не опубликовали ни фрагмента кода, ни деталей каких-либо фреймворков, которые вы можете использовать. Поэтому то, что я предлагаю, основано на ошибке, с которой я часто сталкивался при проверке опроса ajax-кода. Надеюсь это поможет. Если нет, то отредактируйте вопрос и опубликуйте код.

Отказ от ответственности: для краткости я использовал только объект XMLHttpRequest, а не ненависть к продавцу (или любовь). Вы, очевидно, будете использовать функцию создания экземпляров объекта запроса кросс-браузера или, что еще лучше, библиотеку, которая абстрагирует эти кровавые подробности.

Обновления


Итак, ваш код должен обновлять дом каждые две секунды? Пока страница загружена? Без остановки? Я думал, что увижу где-нибудь clearInterval, но в любом случае.

Это немного неловко. Самое близкое, что я получил к такой ситуации, - это когда мне нужно было закодировать импульсную линию, основанную на тикере API, для воспроизведения графика в реальном времени (хорошо, псевдо-в реальном времени при 1 с). Хорошая часть в моем случае заключалась в том, что API работал быстро, со сверхнизкой задержкой, данные, которые я получал, были просто плавающими, а манипуляции с dom, которые я делал с ними, имели незначительную пространственно-временную сложность.

Я обеспокоен тем, что если сервер не отвечает в течение двух секунд или если он работает близко к двум секундам, то у вас есть фрагмент сложного кода, который уже потребляет значительные миллисекунды этих двухсекундных интервалов. Дом не может обновляться каждые две секунды!

  1. Гигиенический совет: избавьтесь от цитат в window.setInterval("refresh()", 2000), Это должно быть просто window.setInterval(refresh, 2000) Причины здесь: утечка памяти для javascript setInterval

  2. Таким образом, $.post определенно будет создавать новые XHR-объекты каждые две секунды в соответствии с кодом. Реально, каково время ответа сервера? Сколько раз цикл setInterval? Например, для низких значений времени отклика менее 10 секунд новые XHR не должны быть проблемой "THE".

  3. 500 строк разбора XML? Каждый интервал? Звучит больно для меня. Можно ли будет токенизировать XML в строку JSON на сервере и вернуть эту строку в пользовательский интерфейс? Это точно сэкономит циклы ЦП клиента.

HTML с 11000 строками. Так что это много обхода и манипуляций с домом. Вот небольшой контрольный список:

  1. Вы используете лучшие селекторы? (специфичность ваших выражений xpath). Шиззл, ты там прикрыл, но постарайся. Такие вещи, как $('p *') могут разрушить.

  2. Вы минимизировали перекомпоновку документа?

  3. Циклы: использование для или сопоставленные функции над массивами являются лучшими (наиболее эффективными)

  4. Доступ к собственности: Вы сокращаете повторный доступ к вложенным свойствам и используете одноразовые ссылки для повышения эффективности?

  5. Добавление / управление эффективностью: например: добавляете ли вы отдельные элементы списка? В идеале вы должны добавить весь список целиком за один раз. То же самое для удалений и т. Д. В основном, короткие, одноразовые манипуляции вместо повторных манипуляций.

Трудно пригвоздить это, не понимая намерений низкого уровня и механики вашего варианта использования.

Наконец, я решил эту проблему. В целом, основным исправлением было изменение сервера ответов на JSON. Я сократил свой ответ до 4 КБ.

Кроме того, я стал более аккуратно манипулировать и добавлять html-элементы в DOM.

Теперь веб-приложение может работать часами, и все работает нормально.

Другие вопросы по тегам