Ужасная производительность при удалении HTML-элемента из UIWebView - PullRequest
1 голос
/ 01 марта 2011

В настоящее время я пишу приложение для iOS, которое использует UIWebView для навигации по страницам.Иногда мне нужно динамически удалять элементы в UIWebView, используя stringByEvaluatingJavaScriptFromString:, но это блокирует основной интерфейс на иногда до 2 секунд на моем первом поколении iPod touch и, возможно, на полсекунды на iPhone 3GS.JavaScript, который я использую для его удаления, просто:

element.parentNode.removeChild(element);

Ничего более сложного, чем это.В то же время я делаю некоторые базовые 2D-рендеринга в OpenGL ES, и если перерисовка UIWebView не заблокируется, я бы использовал простую CoreAnimation в основном потоке.Может ли быть так, что он должен пересчитать дерево DOM, все позиции элементов и т. Д.?Должно ли это действительно заблокировать основной поток пользовательского интерфейса?Это то, что я звоню stringByEvaluatingJavaScriptFromString:, который блокирует все?Это нормально и следовало ожидать на такого рода аппаратных средствах?Странно то, что он способен отображать некоторые полусложные анимации MooTools в веб-просмотре с изменением непрозрачности и высоты, но удаление одного элемента занимает несколько секунд.

У кого-нибудь есть идеи по улучшению?Может быть, лучше просто скрыть элементы, используя visibility: hidden, или установить opacity: 0?Какие-нибудь мысли или мудрые слова опыта?

1 Ответ

4 голосов
/ 04 мая 2011

Работа с деревом DOM ужасно медленная во всех браузерах, особенно в iOS Safari. Ключевым фактором является размер дерева DOM. Из-за этого лучший совет - удалять по ходу (не используйте видимость: скрытый).

Если вы можете избежать использования прямых манипуляций с dom и вместо этого использовать setInnerHTML (), это даст гораздо лучшую производительность. Я видел, как это работает в 100 раз быстрее. Это противоречит интуиции, но выполнение множества манипуляций со строками и последующее бросание строки в браузер происходит намного быстрее. Это связано с тем, что браузеры оптимизированы для визуализации DOM-деревьев из строк.

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

Надеюсь, это поможет.

...