Подтвердить что ты не робот

Но почему браузер DOM все еще так медленно после 10 лет усилий?

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

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

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

Мой вопрос не с запросом what заставляет его медленно, он спрашивает why не стало быстрее?

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

Пример быстрого script:

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

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

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

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

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

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

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

enter image description here

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

Этот вопрос обсуждался на fooobar.com/info/135617/... и Connect (ошибка-трекер). С IE10 проблема решена. Решив, я имею в виду, что они частично перешли на другой способ обновления DOM.

Команда IE, похоже, обрабатывает обновление DOM, подобное команде Excel-macros в 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 для запуска script(вместо нагрузки на тело). Сравните эти две версии:

jsfiddle.net/uAySs/< - body onload

против.

jsfiddle.net/8Kagz/< - кнопка onclick

Почти 2x разница..

По-видимому, основное поведение onload и onclick также меняется. В будущих обновлениях он может стать еще лучше.