Использование 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, которые я делал с ними, имели незначительную пространственно-временную сложность.
Я обеспокоен тем, что если сервер не отвечает в течение двух секунд или если он работает близко к двум секундам, то у вас есть фрагмент сложного кода, который уже потребляет значительные миллисекунды этих двухсекундных интервалов. Дом не может обновляться каждые две секунды!
- Гигиенический совет: избавьтесь от цитат в
window.setInterval("refresh()", 2000)
, Это должно быть простоwindow.setInterval(refresh, 2000)
Причины здесь: утечка памяти для javascript setInterval - Таким образом, $.post определенно будет создавать новые XHR-объекты каждые две секунды в соответствии с кодом. Реально, каково время ответа сервера? Сколько раз цикл setInterval? Например, для низких значений времени отклика менее 10 секунд новые XHR не должны быть проблемой "THE".
- 500 строк разбора XML? Каждый интервал? Звучит больно для меня. Можно ли будет токенизировать XML в строку JSON на сервере и вернуть эту строку в пользовательский интерфейс? Это точно сэкономит циклы ЦП клиента.
HTML с 11000 строками. Так что это много обхода и манипуляций с домом. Вот небольшой контрольный список:
- Вы используете лучшие селекторы? (специфичность ваших выражений xpath). Шиззл, ты там прикрыл, но постарайся. Такие вещи, как $('p *') могут разрушить.
- Вы минимизировали перекомпоновку документа?
- Циклы: использование для или сопоставленные функции над массивами являются лучшими (наиболее эффективными)
- Доступ к собственности: Вы сокращаете повторный доступ к вложенным свойствам и используете одноразовые ссылки для повышения эффективности?
- Добавление / управление эффективностью: например: добавляете ли вы отдельные элементы списка? В идеале вы должны добавить весь список целиком за один раз. То же самое для удалений и т. Д. В основном, короткие, одноразовые манипуляции вместо повторных манипуляций.
Трудно пригвоздить это, не понимая намерений низкого уровня и механики вашего варианта использования.
Наконец, я решил эту проблему. В целом, основным исправлением было изменение сервера ответов на JSON. Я сократил свой ответ до 4 КБ.
Кроме того, я стал более аккуратно манипулировать и добавлять html-элементы в DOM.
Теперь веб-приложение может работать часами, и все работает нормально.