Эффективные и неэффективные селекторы CSS (согласно Google, PageSpeed ​​...) - PullRequest
10 голосов
/ 18 октября 2010

Пытаясь уменьшить размер 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 и т. Д.).

1 Ответ

8 голосов
/ 18 октября 2010

Посмотрите на это недавнее сообщение Джонатана Снука: http://snook.ca/archives/html_and_css/css-parent-selectors

Вы увидите, как браузеры оценивают выражения, и причины, по которым определенные селекторы неэффективны.

Соответствующая цитата из поста:

CSS оценивается справа налево.

Чтобы определить, есть ли правило CSS относится к конкретному элементу, это начинается с права на правило и работает, это путь влево.

Если у вас есть правило, подобное телу div # content p {color: # 003366; } затем для каждого элемента - как он будет представлен на страницу - он сначала спросит, если это элемент абзаца. Если это так, это будет пробраться в DOM и спросить, это div с идентификатором контента. Если он находит то, что ищет, он будет продолжать свой путь вверх по DOM, пока он достигает тела.

Работая справа налево, браузер может определить, применяется ли правило к этому конкретному элементу, что это пытаясь много рисовать в окне просмотра Быстрее. Чтобы определить, какое правило более или менее производительный, вам нужно выяснить, сколько узлов должно быть оценивается, чтобы определить, является ли стиль может применяться к элементу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...