Влияние семантики и DOM-дерева

Давайте рассмотрим сейчас другой вопрос, а именно: как быстро браузер создает DOM- дерево в зависимости от наличия в нем элементов с id или class?

Для этого мы подготовим 3 набора HTML-файлов. Первый будет содержать 10000 элементов, у которых только часть будет иметь id (количество именованных элементов варьируется от 50 до 10000, нужно для оценки влияния DOM-дерева). Второй HTML-файл практически идентичен первому, только элементы вместо id имеют атрибут class. В третьем наборе в DOM-дереве оставим только элементы с id (т.е. будем изменять само число элементов от 50 до 10000). Все измерения запустим в скрытом iframe, чтобы избежать отрисовки загружаемой страницы на экране.

Графики влияния DOM-дерева

Ниже приведены разделенные графики по средневзвешенному значению (естественно, основную роль играет Internet Explorer, ибо сейчас им пользуются от 50% до 70% посетителей наших сайтов) создания документа:

SpeedUpYourWebsite.v1.2_img_30

Рис. 30. Скорость создания документа, средневзвешено по всем браузерам

и график для времени выборки одного элемента из дерева (по идентификатору) при наличии в этом же дереве различного числа элементов с идентификаторами. ID (10000 get) показывает время на 10000 итераций проведения такой выборки, ID clean (10000 get) — то же самое, но в дереве идентификаторы присвоены не всем элементам, а только указанному числу:

SpeedUpYourWebsite.v1.2_img_31

Рис. 31. Скорость выбора элемента, средневзвешено по всем браузерам

Выводы по DOM-дереву

По графику средневзвешенных значений хорошо видно, что, при прочих равных условиях, создание документа с class обходится меньшей кровью, чем с id (в общем случае, от 2% до 10% выигрыша). Если принять во внимание, что .class-селекторы отрабатывают быстрее, чем #id, на те же 10%, то общий выигрыш при использовании в документе классов перед идентификаторами составит порядка 15%. В абсолютном значении эти цифры не так велики: для Centrino Duo 1.7 получается цифра примерно в 0,0085мс на 1 идентификатор (в среднем, 3 CSS-правила и 1 употребление).

Для документа со 100 элементами выигрыш может составить почти 1 мс, для документа с 1000 — 8,5 мс! Стоит заметить, что средняя страница в интернете имеет 500-1000 элементов. Проверить, сколько элементов на странице, можно, просто запустив следующий код в адресной строке браузера на какой-либо открытой странице:

javascript:alert(document.getElementsByTagName(‘*’).length)

Естественно, что приведенные цифры — это уже то, за что можно побороться.

В случае больших веб-приложений задержка в 100 мс (при числе элементов более 10000) уже может оказаться критичной. Ее можно и нужно уменьшать (наряду с другими «узкими» местами для JavaScript, о которых речь пойдет в седьмой главе).

Что и требовалось доказать: значительную нагрузку составляет именно создание DOM- дерева в документе. В целом, на эту операцию уходит от 70% всего времени рендеринга (т.е. наибольшая экономия достигается за счет минимизации размера дерева).

На скорость вычисления одного элемента по идентификатору, как ни странно, наибольшее влияние оказывает опять-таки DOM-дерево, а не количество таких элементов. Даже при 1000 элементов с id более половины временных издержек можно урезать, если просто сократить общее число элементов (особенно хорошо это заметно для IE).

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

Семантическое DOM-дерево

Логическим продолжением уже проведенных исследований CSS/DOM- производительности браузеров стало рассмотрение зависимости времени создания документа от числа тегов (узлов дерева). Раздельно были проанализированы случаи, когда DOM-дерево является чисто линейным (все div лежали прямо внутри body), когда оно разветвленное (ветки по 10 вложенных div наращивались внутри body) и когда вместо ветки из div используются некоторая семантическая конструкция, а именно:

<div>
    <ul> 
        <li></li> 
        <li></li> 
    </ul> 
    <p> 
        <a href=»#»> 
        <em></em>
        </a> 
        <span></span> 
    </p> 
    <blockquote></blockquote> 
    <h1></h1>
</div>

В итоге мы получили примерно следующую картину:

SpeedUpYourWebsite.v1.2_img_32

Рис. 32. Средневзвешенное значение времени создания документа от числа узлов в DOM- дереве

Что быстрее?

Да, очевидно, что размер DOM-дерева влияет на скорость загрузки страницы. Одной из целей данного исследования было показать, как именно влияет (в конкретных числах). Средний размер страницы — 700-1000 элементов. Они загрузятся в дерево сравнительно быстро (3-7 мс, без учета инициализации самого документа, которая занимает 30-50 мс). Дальше время загрузки растет линейно, но все равно можно нарваться на нежелательные «тормоза», добавив несколько тысяч «скрытых» элементов или избыточной семантики.

Различия между линейной и древовидной структурой находятся в пределах погрешности, однако, семантическое дерево оказалось самым медленным (чуть ли не на 50%). Но в любом случае, уменьшение размера DOM-дерева всегда является наиболее приоритетным направлением.

Конечной же целью всех экспериментов было установить, есть ли различие в отображении HTML 4.0 Transitional и XHTML 1.0 Strict документов и какова реальная польза от использования советов по оптимизации CSS-кода (имеется в виду синтаксис селекторов). Об этом рассказывается в следующем разделе.

Методика для DOCTYPE

Была аккуратно выкачана главная страница Яндекса (она уже хорошо оптимизирована с точки зрения производительности, поэтому проводить эксперименты на ней — весьма показательно). Из нее были удалены все ссылки на картинки и внешние скрипты, чтобы не создавать дополнительных задержек. В дальнейшем полученная «чистая» версия препарировалась различными способами.

Далее была добавлена стандартная схема измерения загрузки (рендеринга) страницы: время в самом начале head засекается и затем отнимается от времени срабатывания события window.onload (в данном случае это равносильно окончанию рендеринга HTML- кода). Браузеры друг с другом не сравнивались (в частности, из-за поведения Safari, который не совсем честно сообщает об этом событии), сравнивались только различные варианты.

В качестве второй версии страницы бралось приведение ее к валидному XHTML Strict виду. Верстка при этом немного изменилась, но, в целом, результат получился весьма убедительный. Комментарии и прочий мусор (типа пустых onclick=»», о них речь чуть дальше) были сохранены. Размер, действительно, несколько увеличился (на 1 Кб — несжатая версия и на 150 байтов — сжатая).

Далее в третьей версии уже были убраны все onclick. Больше ничего со страницей не делалось. Ожиданий данная версия не оправдала (только Safari показал значимые отличия от предыдущего варианта, хотя было выкошено 83 пустых onclick).

В четвертом варианте — венце оптимизационных (в отношении CSS/HTML-кода) действий — использование было id сведено к минимуму, все селекторы для class задавались без тегов. Также были убраны все комментарии из кода.

Результаты оптимизации

В таблице приведены результаты для основных браузеров (август 2008): размер каждого вариант в байтах и время его загрузки. Времена приведены в миллисекундах.

  Size (b) Gzip (b) IE6 IE7 IE8b Firefox 2 Firefox 3 Opera 9.5 Safari 3.1

1

26275

8845

56

80

76

130

127

142

33

2

27173

8993

60

75

320

127

118

148

27

3

26260

8949

61

75

320

131

116

141

23

4

26153

8862

55

73

306

94

102

178

28

Таблица 7. Для каждого варианта приведен размер и время его отображения в миллисекундах

«Экономия на спичках»?

В результате тестов удалось показать, что валидный XHTML не медленнее (а даже, местами, быстрее), чем HTML. И оптимизация реально играет роль (возможно ускорение загрузки HTML главной страницы Яндекса на 10-12%). Если говорить о конкретных примерах, то на 100 Кб/с канале с включенным сжатием в FF3 оптимизированный вариант загрузится на 9 мс быстрее. Для более быстрого канала или более медленного компьютера отличие будет еще разительнее.

Естественно, это все «копейки» для обычных пользователей (+/-50мс — это совершенно не критично). Однако если речь идет про «экономию на спичках», когда нам важен каждый запрос к серверу и каждая миллисекунда, то тут уже стоит задуматься — что же все-таки использовать.

И что важнее всего, если правильно расставить акценты, то загрузку XHTML можно сделать и быстрее, чем HTML. Различие в размере файлов оказалось, в итоге, минимальным (26153 против 26275 в несжатом варианте, и 8862 против 8845 в сжатом, т.е. меньше 0,5%). При этом в IE7 наблюдается ускорение отображения страницы на 7 мс (от 60-80 мс при загрузке страницы). Это, в среднем, дает 10% выигрыша в скорости. FF3 ведет себя похожим образом (но выигрыш в скорости 20% (25 мс от 127 мс)). Все остальные браузеры показали отличие в загрузке на 2-3 мс, что укладывается в погрешность; Opera была медленнее, что подтверждается предыдущими тестами.

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

Posted in Разгони свой сайт.