Как я могу контролировать утечки памяти в IE6 + jQuery + jQuery-ui? - PullRequest
28 голосов
/ 27 июня 2009

Вот пример страницы с парой сборщиков даты. Вот результат Drip для этого:

альтернативный текст http://www.picvault.info/images/537090308_omoya.png

Эта страница просачивается на неопределенное время в IE6sp1, когда я нажимаю кнопку Обновить несколько раз (IE6sp3 +, Opera 9, Chrome2 и FF3 + кажутся хорошими). Память увеличивается и никогда не падает, пока я не закрою браузер полностью.

Я также пытался использовать последний ночной jquery (r6414) и последний стабильный интерфейс (1.7.2), но это не имело никакого значения. Я пробовал разные вещи безуспешно ( CollectGarbage , AntiLeak , другие).

Я ищу решение, отличное от «использовать другой браузер !! 1», так как я не могу это контролировать. Любая помощь будет принята с благодарностью!

Обновление 1: Я добавил это событие кнопки в цикл, и вот что происходит (внезапное падение происходит, когда я прекращаю работу IE): alt text

Обновление 2: Я подал отчет об ошибке (скрестив пальцы).

Обновление 3: Это также входит в список рассылки .

Обновление 4: Это (как указано в списке рассылки) не работает, и фактически ухудшает ситуацию:

$(window).bind("unload", function() {
  $('.hasDatepicker').datepicker('destroy');
  $(window).unbind();
}); 

Недостаточно просто вызвать уничтожение. Я все еще застрял с этим и очень близок к тому, чтобы вырвать jquery из проекта. Я люблю это (я действительно делаю!), Но если это сломано, я не могу использовать это.

Обновление 5: Начиная награду, еще 550 указывает на одного полезного человека!

Обновление 6: Еще несколько испытаний показали, что эта утечка существует в IE6 и IE6sp1, но была исправлена ​​в IE6sp2 +. Теперь об ответах, которые у меня есть ...

Пока что все ответы были на один из них:

  1. Отказаться от пользователей IE6sp0 / sp1 или игнорировать их
  2. Отладка jquery и устранение проблемы самостоятельно
  3. Я не могу воспроизвести проблему.

Я знаю, что нищие не могут выбирать, но это просто не ответы на мою проблему.

Я не могу отказаться от своих пользователей. Они составляют 25% пользовательской базы. Это пользовательское приложение, написанное для клиента, предназначенное для работы на IE6. Нельзя отказаться от IE6sp0 / sp1. Нельзя сказать моим клиентам просто разобраться с этим. Он протекает так быстро, что через пять минут некоторые из более слабых машин становятся непригодными для использования.

Кроме того, хотя мне бы хотелось стать ниндзя JS, чтобы я мог выискивать скрытые утечки памяти в коде jquery (если это вина MS, а не jquery), я также не вижу, чтобы это происходило.

Наконец, несколько человек воспроизвели проблему здесь и в списке рассылки. Если вы не можете воспроизвести его, возможно, у вас IE6SP2 + или недостаточно обновления.

Очевидно, что этот вопрос очень важен для меня (отсюда 6 ревизий, щедрость и т. Д.), Поэтому я открыт для новых идей, но имейте в виду, что ни одно из этих трех предложений не сработает для меня.

Спасибо всем за внимание и понимание. Пожалуйста, продолжайте их!

Обновление 7: Щедрость закончилась, и ответ Кейта был автоматически принят SO. Я сожалею, что была награждена только половина баллов (так как я сам не выбрал ответ), но я все еще застрял, так что я думаю, что половина справедлива.

Я надеюсь, что команда jquery / jquery-ui сможет решить эту проблему, но я боюсь, что мне придется списать это как «невозможно (пока)» и прекратить использовать некоторые или все jquery. Спасибо всем за вашу помощь и внимание. Если кто-то придет с реальным решением моей проблемы, пожалуйста, напишите, и я найду способ как-то вас наградить.

Ответы [ 9 ]

21 голосов
/ 16 июля 2009

Мне неприятно это говорить, ваш подход правильный и профессиональный, но я бы соблазнился просто оставить его.

Последствия отсутствия исправления состоят в том, что пользователи IE6 заметят, что их машина работает все медленнее и медленнее и, в конечном итоге, либо полностью выходит из строя, либо, скорее всего, происходит сбой IE6.

И что?

Действительно - почему это ваша проблема?

Ваш сайт определенно не будет единственным сайтом, который они посещают с этой утечкой, и они будут регулярно видеть сбой IE6 независимо от того, что вы делаете, потому что это то, что он делает.

Маловероятно, что кто-либо еще в IE6 мог бы даже указать, что ваше приложение имеет утечку.

Наконец, когда IE6 действительно падает, он сообщает об IE6 как о виновнике - вы можете на законных основаниях указать, что это ошибка в IE6, которую Microsoft исправила в новой версии.

Ваше дорогое время лучше потратить на улучшение приложения для пользователей, не попавших в унылый ад - ваше приложение должно в основном работать для пользователей IE6, но такого рода проблемы могут отнять у вас все время и не решить их проблему. IE6 по-прежнему будет неподдерживаемой дырой в безопасности браузера.

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


Обновление

Хорошо, это не простая проблема - MS описывает ошибку IE6 (и дает советы по ее устранению) здесь: http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx

По сути, это не проблема с javascript или jQuery - реальная проблема с IE6 DOM - когда HTML-элементы добавляются на страницу (с помощью javascript, а не на странице при загрузке) IE не может мусор собирать их, если они не созданы особым образом.

Это задом наперед от того, как jQuery UI создает элементы (см. Ошибку порядка вставки DOM в ссылке выше), и поэтому это не то, что разработчики jQuery или вы можете легко исправить.

Так как вы решаете проблему? Что ж, вы можете использовать устаревший всплывающий календарь для IE6 или написать свой собственный.

Я бы порекомендовал первое, но если вы действительно хотите построить второе, есть несколько основных правил, которым нужно следовать:

  1. Всегда добавляйте элементы сверху вниз - например, если вы хотите построить таблицу, добавьте элемент <table> в DOM страницы, затем добавьте <tr>, затем <td> и так далее. Это задний план, так как гораздо быстрее построить всю таблицу и затем добавить ее в DOM - к сожалению, именно здесь IE6 теряет контроль.

  2. Использовать только атрибуты CSS и HTML 3.2 - звучит глупо, но IE6 создает дополнительные объекты для хранения дополнительных атрибутов (или свойств "expando"), и они также протекают.

  3. В некотором роде относится к (2), но, как упоминает @gradbot, IE6 имеет проблемы с сборкой мусора переменных javascript - если они ссылаются на элемент DOM внутри события, инициируемого этим элементом, вы можете получить проблемы. Это также усугубляется ссылками javascript на элементы DOM, обладающие свойствами 'expando'.

Если вы посмотрите в Интернете, возможно, уже есть выпадающий календарь DHTML, который соответствует этим правилам - он не будет таким же красивым, быстрым или настраиваемым, как пользовательский интерфейс jQuery, но я уверен, что ' Я видел, что это сделано без утечки в IE6.

Я думаю, что лучше всего сохранять как можно больше статичности - например, вы можете загрузить сетку календаря (номера недель и заголовки столбцов дней) со страницей, а затем динамически загружать цифры (и ничего больше). Создайте номера дней в виде ссылок с использованием javascript в href - обычно это не лучшая практика, но гораздо менее вероятная утечка в IE6.

4 голосов
/ 17 июля 2009

Очевидно, что проблемы, которые вы описывали, проистекают из недостатка IE6, который вы не можете устранить с помощью исправления программного обеспечения (будь то обновление jQuery, ручной вызов CollectGarbage или какой-то другой взлом JavaScript / DOM) .

На мой взгляд, есть 3 варианта решения этой проблемы.

  1. Я полагаю, что ваши клиенты / пользователи используют IE6 SP0 из-за какого-то стандарта или норматива компании или даже из-за того, что какое-то старое веб-приложение, которое они все еще используют, не поддерживает новые браузеры. Если нет возможности перейти на IE7 (или, следовательно, IE8), вы можете связаться с ИТ-отделом своих клиентов и вежливо указать, что обновление IE6 с помощью последних пакетов обновления не только решит проблему с приложением, которым они являются. платить, но также исправлять многие недостатки безопасности и производительности, которые, несомненно, существуют в IE6 SP0. По общему признанию, это может быть неудобной ситуацией, но это может решить проблемы, с которыми вы сталкиваетесь, и в то же время позволить им работать с браузером, который требует по любой причине.

  2. Если вы можете убедить ИТ-отдел ваших клиентов в том, что IE6 устарел, они могут захотеть позволить вашим пользователям перейти на более новый браузер. Нетрудно сказать, что кто-то, работающий в ИТ-отделе, будет более склонен заставлять сотрудников обновлять программное обеспечение, если они знают, что оно либо а) изобилует недостатками и пробелами в безопасности, либо б) приближается к дате окончания поддержки (как IE6 SP0 есть). IE6 SP0 в XP Pro SP2 поддерживается до 13 июля 2010 г., поэтому у него все еще есть время, но указание на это, наряду с другими недостатками / ограничениями, которые вы можете обнаружить, может заставить их всерьез задуматься об обновлении раньше, чем позже.

  3. Если вы не можете никого убедить обновить свои браузеры до IE6 SPX или IE7 / 8, то я не знаю, есть ли у вас выбор, кроме как удалить нарушающий контроль элемент со своей страницы, и придерживайтесь другой опции, пока браузер пользователя не разрешит это. Несомненно, есть много реализаций элемента управления выбора даты, доступных в Интернете, которые будут соответствовать вашим потребностям. Это может быть не так привлекательно, как версия jQuery, но у вас нет других вариантов на этом этапе.

Надеюсь, вы найдете решение!

2 голосов
/ 13 июля 2009

попробуйте удалить эти объекты после уничтожения объекта datepicker:

$.datepicker = null;
$.fn.datepicker = null;
2 голосов
/ 29 июня 2009

Эта проблема возникает либо в части jQuery, предназначенной только для IE6, либо в общей части jQuery, в которой отсутствует специальный код IE6 (как отмечено в комментариях). В любом случае, это все еще ошибка в jQuery, которая требует устранения. о: пусто Вам придется либо копаться в jQuery , либо подать заявку на ошибку . Если вам удастся это исправить, не забудьте прикрепить diff к багтрекеру, так что проект станет немного лучше. ;)

Если у меня будет свободное время, я постараюсь помочь вам в этом.

Редактировать

Хорошо, проблема кажется непреодолимой.

Утечка, с которой вы сталкиваетесь, является единственной проблемой IE 6 SP 0, утечка, вызванная подходом IE к DOM. Неважно, какую платформу JS вы используете, она отказывается работать правильно.

Итак, ваши текущие параметры:

  • Умереть, пытаясь заставить своих пользователей обновить IE 6 до более новой версии / Service Pack,
  • Die (как в утечке) в IE (потеря клиентов) или
  • Die пытается работать на IE.

Но это не обязательно означает, что вы не можете решить это. Как насчет того, чтобы просто попытаться сбить с толку эту штуку?

Покажите каждому пользователю, не являющемуся пользователем IE 6 SP 0, средство выбора даты jQuery, и только IE 6 SP 0 - еще один более гибкий (и, вероятно, базовый) средство выбора даты с условными комментариями IE . Таким образом, вы можете следить за функциональностью своего программного обеспечения и позволить пользователям IE 6 иметь те же базовые функции.

Возможно, это не совсем чистый вариант, но вы все равно сможете использовать то, что хотите, и IE6 все равно сможет работать без утечек.

Проблема only заключается в том, что у вас будет больше бремени за счет выгрузки двух разных сборщиков дат. Но вам все равно придется отлаживать IE 6, так что на данный момент это может быть вашим лучшим выбором.

1 голос
/ 17 июля 2009

Проблема здесь кроется немного глубже, чем «просто» jquery. Jquery, как и многие другие браузеры, «пропускает» циклические ссылки между объектами DOM и слушателями объектов. Скажем, у вас есть поле ввода, к которому прикреплен слушатель, затем вы удаляете элемент из dom и не имеете никакой ссылки на слушателя в вашем коде. Теперь любой современный браузер (> = ie7, ff, chrome, safari, opera) будет жить с этим и собирать мусор, в то время как IE6 будет думать, что, поскольку к элементу dom подключен слушатель, он не должен собирать мусор dom и сам слушатель.

Чтобы обойти это, некоторые люди используют очень сложные шаблоны проектирования, как выделено, например, в коде событий в Google Doctype. Чтобы исправить проблему для IE6, вам действительно нужно переписать часть jquery, чтобы обойти проблему IE6 и / или переключиться на использование другой библиотеки и / или не присоединять какие-либо прослушиватели событий в вашем приложении к событиям DOM.

1 голос
/ 03 июля 2009

Проблема с IE 6 состоит в том, что у него есть два сборщика мусора. Один для JavaScript и один для DOM. Например, если вы присоединяете функцию к событию DOM, а затем удаляете элемент DOM, функция все равно будет существовать в памяти.

Проверьте это слайд-шоу . Это немного язык в щеке, но это хорошая информация.

Они исправили эту проблему в IE 7. Я попробовал вашу страницу в IE8 в Windows 7 и не вижу утечки памяти.

0 голосов
/ 01 марта 2012

Посмотрите на этот фрагмент, который очищает DOM-узлы. Вы можете найти это полезным. https://stackoverflow.com/a/9519996/139667

0 голосов
/ 14 июля 2009

Можете ли вы попробовать это демо здесь . Он использует тот же метод, который реализует dojo для удаления элементов из dom. Некоторое быстрое тестирование облегчает утечку, но не полностью, а намного лучше.

ОБНОВЛЕНИЕ Потратив немного времени на это, я убежден, что это никак не связано с самим средством выбора даты.

Мои тесты показывают, что просто перезагружая фиктивную страницу каждую 1 секунду, то есть происходит утечка памяти. Если затем вы включите jquery на эту страницу, утечки немного возрастут (непроизводительные затраты при разборе скрипта). Если затем вы добавите jquery-ui в микс, то снова произойдет небольшое увеличение утечки памяти.

Чтобы доказать это, если вы избегаете перезагрузки страницы и вместо этого имеете кнопку, которая просто добавляет ввод, создает на нем указатель даты, а затем удаляет его, вы видите очень мало утечек.

0 голосов
/ 29 июня 2009

Лучший отладчик для IE6 - Visual Studio. (Даже бесплатная версия будет работать.) Как упоминает Джени, если ваша проблема возникает только в IE6, вы захотите отладить ее в IE6, обращая особое внимание на код, который там только запускается.

...