Опубликован: 16.02.2009 | Уровень: специалист | Доступ: платный
Лекция 6:

CSS-оптимизация

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >

Выводы

Единственный вывод, который можно с твердостью сделать, — это преимущество использования #id перед p#id (средневзвешенное по всем браузерам для Рунета получается 9%). Также можно с некоторой уверенностью говорить об использовании .class вместо p.class (10%). Еще стоит обратить внимание на существенное (до 2,5 раз) ускорение при переходе от CSS1-селекторов к CSS2 (от div p к div>p, в тех браузерах, которые это поддерживают). Дополнительно нужно, наверное, отметить, что выборка элементов по классу работает в целом быстрее, чем по идентификатору (11%).

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

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

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

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

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

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

 Время создания документа (средневзвешено по всем браузерам)

Рис. 6.1. Время создания документа (средневзвешено по всем браузерам)

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

 Скорость выбора элемента (средневзвешено по всем браузерам)

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

Выводы по 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>

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

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

Рис. 6.3. Средневзвешенная скорость cоздания документа от числа узлов в 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): размер каждого варианта в байтах и время его загрузки. Времена приведены в миллисекундах.

Таблица 6.2. Для каждого варианта приведен размер и время его отображения в миллисекундах
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 8980 61 75 320 131 116 141 23
4 26153 8862 55 73 306 94 102 178 28
< Лекция 5 || Лекция 6: 12345 || Лекция 7 >
Дарья Билялова
Дарья Билялова
Россия
Елена Петрушевская
Елена Петрушевская
Россия, г. Нижневартовск