spam poison

Разгоняем CSS-селекторы. Часть 2: транзитивность


Рассмотрим несколько дополнительных случаев, учитывающих транзитивность селекторов (например, насколько быстрее a c, чем a b c, или наоборот). Данное исследование посвящено как раз разбору таких случаев.


Методика

Методика и уменьшение погрешности подробно рассматривались в первой статье, на них сильно много останавливаться не буду. Скажу лишь, что при наращивании количества классов и идентификаторов Opera стала значительно медленнее (раза в 3) отображать код (при этом общий его объем увеличился примерно в 1,5-2 раза). Скорее всего, в следующую статью войдет исследование влияния количества классов/идентификаторов/размера кода на общую производительность браузера.

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

Для возможности работать с транзитивностью в (практически) полном объеме в исходную структуру документа были добавлены элементы третьего уровня (a). В итоге, сам документ представлял большое линейное дерево, каждый из узлов которого являлся <div><p><a></a></p></div> (с соответствующими классами или идентификаторами).

Тестовые случаи

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

  1. a.class
  2. p a.class
  3. div a.class
  4. div p a.class

Далее выяснялось, насколько в браузерах оптимизирована транзитивность по идентификаторам:

  1. #id1
  2. #id2 #id1
  3. #id3 #id1
  4. #id3 #id2 #id1

Затем смешанная транзитивность (по классам и по тегам):

  1. p.class2 a.class1
  2. div.class3 a.class1
  3. div.class3 p.class2 a.class1
  4. div.class3 p a.class1

Затем по идентификаторам и по тегам:

  1. p a#id1
  2. div a#id1
  3. div p a#id1
  4. div p#id2 a#id1

Загрузить все исходные файлы, равно как и пройти тест онлайн можно по адресу webo.in/tests/css-efficiency-2/.

Результаты

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

Пары селекторов Firefox 2.0 Opera 9.5 Safari 3 IE 7 IE 6
a.class 1617 9119 326 169 133
p a.class 1697 9872 331 158 134
div a.class 1661 10905 378 162 127
div p a.class 1469 11667 344 169 127
 
#id1 1202 34200 335 164 123
#id2 #id1 1559 33235 320 169 130
#id3 #id1 1656 35355 324 169 133
#id3 #id2 #id1 1214 34608 397 175 137
 
p.class1 a 2160 12675 342 150 108
div.class2 a 2052 11971 369 153 108
div.class2 p.class1 a 1511 12217 420 156 116
div.class2 p a 1878 11871 366 150 110
 
p a#id1 1425 13163 359 166 122
div a#id1 1506 10572 341 156 116
div p a#id1 1474 12195 344 159 123
div p#id2 a#id1 1233 11916 353 169 133

Скорость работы CSS-селекторов

Выводы

Во-первых, сразу видно, что наследование селекторов по идентификаторам хорошо оптимизировано в браузерах (только не рекомендуется использовать более 2 подряд), средний выигрыш от использования 1 идентификатора вместо 2 или 3 невелик. Safari/Opera дали некоторый крен в сторону 2 идентификаторов, но, по моему мнению, это, скорее всего, связано с погрешностью эксперимента, ибо представить ситуацию, что две операции происходят быстрее, чем одна, достаточно тяжело.

Во-вторых, IE лучше себя ведет в наследовании классов/тегов: конструкции вида p.class2 a.class1 отрабатывают несколько быстрее, чем a.class1. Подозреваю, что это связано с первоначальным сужением области перебора элементов. Когда мы выбираем один из узлов очень плоского дерева, то поиск внутри этого узла идет значительно быстрее, чем изначальный перебор всех возможных вариантов по дереву (в данном примере с помощью конструкции div(#id)). Средневзвешенный выигрыш: 9%.

Наследование тегов не дает никакого особого преимущества перед обычным использованием классов, но в некоторых случаях может оказаться быстрее (выигрыш в пределах погрешности). С наследованием идентификаторов и тегов ситуация очень похожа на наследование классов, наверное, браузеры также оптимизированы на разрешение ситуации, когда на странице используется несколько идентификаторов, поэтому сужение области перебора несколько ускоряет ситуацию.

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

Если у кого-то появятся идеи, как можно еще расширить имеющийся набор тестов, — стоит их обсудить. Спасибо за интерес к заметке.



Article information
Wroted: Tue, 18 Mar 2008 11:21:00 EET
Autors: Николай Мациевский a.k.a sunnybear
Added by: AlexParamonov at Tue, 09 Dec 2008 11:21:52 EET
Translation information
Added by: AlexParamonov at Tue, 09 Dec 2008 11:23:16 EET
Modified by: AlexParamonov at Tue, 09 Dec 2008 12:33:18 EET
Copyright © 2008-2010 Alexander Paramonov
Valid XHTML 1.0 Transitional