Но почему браузер DOM все еще такой медленный после 10 лет усилий? - PullRequest
44 голосов
/ 25 июля 2011

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

У нас есть некоторые из самых блестящих умов в мире от Google, Mozilla, Microsoft, Opera, W3C и различных других организаций, работающих над веб-технологиями для всех нас, так что, очевидно, это не просто "О,мы не оптимизировали его ».

Мой вопрос: Если бы я работал над той частью веб-браузера, которая конкретно занимается этим вопросом, с чего бы мне было так трудновремя заставляет его работать быстрее?

Мой вопрос не спрашивает что делает это медленно, он спрашивает почему разве это не стало быстрее?

Это, похоже, противоречит тому, что происходит в других местах, например, движкам JS с производительностью, близкой к производительности кода C ++.

Примербыстрого скрипта:

for (var i=0;i<=10000;i++){
    someString = "foo";
}

Пример медленного из-за DOM:

for (var i=0;i<=10000;i++){
    element.innerHTML = "foo";
}

Некоторые детали по запросу:

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

Похоже, эффективность DOM сильно различается в разных браузерах, но мое первоначальное предположение, что dom медленный и неразрешимый, кажется неправильным.

Я провел тесты с Chrome, FF4 и IE 5-9, вы можете увидеть количество операций в секунду на этом графике:

enter image description here

Chrome работает молниеносно, когда вы используете DOMAPI, но значительно медленнее с использованием оператора .innerHTML (в 1000 раз медленнее), однако FF хуже, чем Chrome, в некоторых областях (например, тест на добавление намного медленнее, чем Chrome), но тест InnerHTML работает намногобыстрее, чем chrome.

IE, похоже, на самом деле ухудшается при использовании DOM append и лучше при работе с innerHTML по мере прохождения версий с 5.5 (т. е. 73опс / с в IE8 теперь при 51 ops / sec в IE9).

У меня есть тестовая страница здесь:

http://jsperf.com/browser-dom-speed-tests2

Интересно то, что кажется, что разные браузеры сталкиваются с разными проблемамиs при генерации DOM.Почему здесь такое несоответствие?

Ответы [ 3 ]

47 голосов
/ 25 июля 2011

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

Это не единственная причина: когда вы устанавливаете element.innerHTML=x, вы небольше не имеет дело с обычными переменными «сохранить значение», но со специальными объектами, которые обновляют загрузку внутреннего состояния в браузере, когда вы их устанавливаете.

Полные последствия element.innerHTML=x огромны.Примерный обзор:

  • синтаксический анализ x как HTML
  • запрос разрешения расширений браузера
  • уничтожение существующих дочерних узлов element
  • createдочерние узлы
  • пересчитывают стили, которые определены в терминах родительско-дочерних отношений
  • пересчитывают физические размеры элементов страницы
  • уведомляют браузерные расширения об изменении
  • обновить переменные Javascript, которые являются дескрипторами для реальных узлов DOM

Все эти обновления должны проходить через API, который соединяет Javascript и механизм HTML.Одна из причин того, что в наши дни Javascript настолько быстр, что мы компилируем его в какой-то более быстрый язык или даже машинный код, происходит масса оптимизаций, потому что поведение значений четко определено.При работе через DOM API, * невозможно.Ускорения в других местах оставили DOM позади.

4 голосов
/ 08 ноября 2012

Автором оригинального теста является Hixie (http://nontroppo.org/timer/Hixie_DOM.html).

Эта проблема обсуждалась здесь также StackOverflow и Connect (bug-tracker) . С IE10проблема решена. Под разрешением я имею в виду, что они частично перешли на другой способ обновления DOM.

Команда IE, кажется, обрабатывает обновление DOM, аналогичное команде макросов Excel в Microsoft, где она считаетсяплохая практика обновления живых ячеек на листе. Предполагается, что вы, разработчик, переводите тяжелую задачу в автономный режим, а затем обновляете живую команду в пакетном режиме. В IE вы должны делать это, используя фрагмент документа (в отличие отдокументировать.) С появлением новых стандартов ECMA и W3C, фрагменты документов устарели. Поэтому команда IE проделала довольно хорошую работу, чтобы решить эту проблему.

Им потребовалось несколько недель, чтобы урезать ее с~ 42 000 мс в IE10-ConsumerPreview до ~ 600 мс IE10-RTM . Но потребовалось немало усилий, чтобы убедить их, что это проблема. Они утверждали, чтоне существует реального примера, который имеет 10 000 обновлений на элемент.Поскольку объем и характер многофункциональных интернет-приложений (RIA) не могут быть предсказаны, крайне важно иметь производительность, близкую к другим браузерам лиги.Вот еще один пример использования DOM с помощью OP на MS Connect (в комментариях):

Когда я перехожу к http://nontroppo.org/timer/Hixie_DOM.html,, это занимает ~ 680 мс, и если я сохраняю страницу и запускаю ее локально,это занимает ~ 350 мс!

То же самое происходит, если я использую событие button-onclick для запуска скрипта (вместо body-onload).Сравните эти две версии:

jsfiddle.net / uAySs / <- нагрузка на тело </p>

против

jsfiddle.net / 8Kagz / <- нажатие кнопки </p>

Разница почти в 2 раза.

Очевидно, что базовое поведение onload и onclick также различается.Это может стать еще лучше в будущих обновлениях.

4 голосов
/ 25 июля 2011

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

Во-вторых, innerHTML - не простая операция. Это грязный взлом, который подтолкнул MS, и другие браузеры приняли его, потому что он настолько полезен; но это не часть стандарта (IIRC). Используя innerHTML, браузер должен проанализировать строку и преобразовать ее в DOM. Разбор это сложно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...