Пытаясь уменьшить размер HTML веб-страницы, я натолкнулся на предложения Google и дополнения PageSpeed Firefox, касающиеся эффективности селекторов CSS, которые (почти) заставили меня пересмотреть изменения:
http://code.google.com/intl/de-DE/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
В частности, селекторы-потомки отлично подходят для выбора целого блока (например, DIV) с использованием атрибута ID или CLASS, а затем сохранения всех его дочерних элементов свободными от атрибутов CLASS / ID.Но если порядок обхода для применения правил соответствует описанию Google, их не следует использовать:
Селекторы потомков неэффективны, поскольку для каждого элемента, который соответствует ключу, браузер также должен проходитьвверх по дереву DOM, оценивая каждый элемент-предок, пока он не найдет совпадение или не достигнет корневого элемента.Чем менее конкретен ключ, тем больше число узлов, которые необходимо оценить.
Я очень сомневаюсь, что браузеры используют такой неэффективный порядок обхода, конечно, они будут обрабатывать только поддеревья элементов, которыесоответствует верхнему компоненту селектора, т.е. в #foo span {...}
должны проверяться только элементы ниже #foo, а не каждый отдельный диапазон.Может ли кто-нибудь, кто просматривал недавний код браузера, подтвердить или опровергнуть это?
Второе сомнительное предложение касается чрезмерно квалифицированных селекторов:
Селекторы ID уникальны по определению.Включение квалификаторов тегов или классов просто добавляет избыточную информацию, которую необходимо оценивать без необходимости.
Если селекторы идентификаторов по определению уникальны, зачем браузерам проверять избыточную информацию?Я знаю, что они делают, потому что, например,
div # foo {color: black;} #foo {color: white;}
приведет к черному тексту в <div id=foo>
, но а) этого не следует делать (нужна ссылка W3C) и б) я не понимаю, почему это будет заметно медленнее, когдаэто приводит к простой O (1) проверке имени тега элемента.
Может ли кто-нибудь в хороших отношениях с исходным кодом современных браузеров пролить свет на эти утверждения?Поскольку большинство современных сайтов используют селекторы потомков (включая SO), и они имеют явные преимущества, я бы очень хотел использовать их ...
Редактировать:
IЯ немного поэкспериментировал со сгенерированными страницами, и кажется, что обработка в браузерах потомков-селекторов действительно жалкая:
Страница, состоящая из (сокращенно):
# top a {оформление текста: нет;}
# foo1 a.foo {цвет: красный;}
# foo2 a.foo {цвет: красный;}
[..повторяется 10000 раз]
... [вложено 50 раз] бла
[...]
[предыдущая строка повторена 10000 раз]
(в основном 10000 строк с 50 вложенными делителями в каждой для прохождения до корневого узла и 1 селектор, который соответствует 10000)
загружает и рендерит (время до window.onload()
выполнения) за 2,2 секунды, используя Safari 5 и простодо 10 секунд с Firefox 3.6.10.
Когда селектор класса .foo
удален из неприменимых правил, страница занимает около 200 секунд с Safari 5 и 96 секунд с Firefox 3.6.10.Это показывает, насколько плохо реализованы селекторы-потомки (в этом случае каждое из 10000 правил, вероятно, вызывает обход до #top, где правило не выполняется).
Как обходятся дочерние селекторы?#foo > span > div > div > div > div > div a {color: red;}
(также никогда не совпадает, но форсирует обход 6 родительских узлов) в Safari 5 и 31 секунде с Firefox 3.6.10.
Заключение
Потомоки дочерние селекторы оба сосут в настоящее время в основных браузерах.Еще лучше добавить некрасивые атрибуты class / id во все ваши стилизованные теги, если вы заботитесь о скорости, по крайней мере для очень распространенных тегов HTML (таких как, img, div и т. Д.).