Проблемы с производительностью Javascript из-за слишком большого количества узлов dom?

В настоящее время я отлаживаю чат ajax, который просто бесконечно заполняет страницу DOM-элементами. Если у вас есть чат, который длится около 3 часов, вы получите бог знает сколько тысяч DOM-узлов.

Какие проблемы связаны с экстремальным использованием DOM?

Возможно ли, что пользовательский интерфейс полностью перестает отвечать на запросы (особенно в Internet Explorer)?

(И в связи с этим вопросом, конечно, решение, если есть какие-либо другие решения, кроме ручной сборки мусора и удаления узлов dom.)


person Jens    schedule 06.12.2010    source источник
comment
Вы испытываете проблемы или просто говорите теоретически? Если да, можете ли вы дать URL-адрес или хотя бы более подробную информацию о том, какие замедления вы видите (при подключении новых узлов, при прокрутке, событиях ajax и т. д.). Вы должны попробовать dynatrace.com/en   -  person gblazex    schedule 06.12.2010


Ответы (3)


Большинство современных браузеров должны хорошо справляться с огромными деревьями DOM. И «большинство» обычно не включает IE.

Так что да, ваш браузер может перестать отвечать (потому что ему нужно слишком много оперативной памяти -> подкачка) или потому что его рендерер просто перегружен.

Стандартное решение — удалить элементы, скажем, после того, как на странице будет 10 000 строк чата. Даже 100 000 строк не должны быть большой проблемой. Но я бы начал чувствовать себя неловко из-за чисел, намного превышающих это (скажем, миллионы строк).

[EDIT] Еще одна проблема — утечка памяти. Несмотря на то, что JS использует сборку мусора, если вы сделаете ошибку в своем коде и сохраните ссылки на удаленные элементы DOM в глобальных переменных (или ссылки на объекты из глобальной переменной), вы можете исчерпать память, даже если на самой странице содержится всего несколько тысяч элементов.

person Aaron Digulla    schedule 06.12.2010
comment
Спасибо. Всегда трудно понять, сколько dom-элементов может обрабатывать браузер, но я согласен с тем, что вообще не стоит ограничивать количество строк чата, отображаемых в сеансе чата. Лучшее решение - иметь какое-то представление истории. Поскольку я не могу перестроить все это, некоторые луки-пореи трудно исправить, но я добавил ручную сборку мусора. - person Jens; 06.12.2010

Просто наличие большого количества узлов DOM не должно быть большой проблемой (если у клиента не хватает оперативной памяти); однако манипулирование множеством узлов DOM будет довольно медленным. Например, перебор группы элементов и изменение цвета фона каждого из них — это нормально, если вы делаете это для 100 элементов, но может занять некоторое время, если вы делаете это для 100 000. Кроме того, некоторые старые браузеры имеют проблемы при работе с огромным DOM-деревом — например, прокрутка таблицы с сотнями тысяч строк может быть неприемлемо медленной.

Хорошим решением этой проблемы является буферизация представления. По сути, вы показываете только те элементы, которые видны на экране в любой момент, а когда пользователь прокручивает страницу, вы удаляете скрытые элементы и показываете те, которые открываются. Таким образом, количество узлов DOM в дереве относительно постоянно, но вы ничего не теряете.

Еще одно похожее решение — ввести ограничение на количество сообщений, отображаемых в любой момент времени. Таким образом, любые сообщения после, скажем, 100 будут удалены, и чтобы увидеть их, вам нужно нажать кнопку или ссылку, которая показывает больше. Это своего рода то, что Facebook делает со своими профилями, если вам нужна ссылка.

person Sasha Chedygov    schedule 08.12.2010

Проблемы с экстремальным использованием DOM могут сводиться к производительности. Сценарии DOM очень дороги, поэтому постоянный доступ к DOM и манипуляции с ним могут привести к снижению производительности (и пользовательского опыта), особенно когда количество элементов становится очень большим.

Рассмотрим, например, коллекции HTML, такие как document.getElementsByTagName('div'). Это запрос к документу, и он будет выполняться повторно каждый раз, когда требуется актуальная информация, например длина коллекции. Это может привести к неэффективности. Худшие случаи будут иметь место при доступе и управлении коллекциями внутри циклов.

Есть много соображений и примеров, но, как и все, это зависит от приложения.

person Chocula    schedule 08.12.2010