Ускорение двух правил CSS: с указанием / без указания нескольких идентификаторов - PullRequest
5 голосов
/ 24 января 2011

Итак, я недавно много работал с Concrete5. Однако я заметил, что тема по умолчанию имеет много правил CSS, которые определены следующим образом:

#page #central #sidebar p{line-height:24px}

Поскольку «боковая панель» является идентификатором, на всей странице должна быть только одна «боковая панель» (при условии, что она проверяет, что я позаботился о ней). Поэтому, если #sidebar находится в #page #central, оно должно всегда быть в #page #central. Не важно что. На каждой странице.

По этой логике следующее правило делает то же самое:

#sidebar p{line-height:24px}

Тестирование это, конечно же, это сработало. Так что мой вопрос - что будет лучше? Есть ли причина, связанная со скоростью, что команда Concrete5 пошла с более длинной спецификацией, или это было просто для того, чтобы помочь будущим разработчикам найти #sidebar div? Я вижу аргументы в пользу того, что это будет быстрее в любом случае.

Если случай 1 быстрее (#page #central #sidebar):

Если браузер использует алгоритм поиска в ширину для поиска правильного элемента DOM, то поиск #sidebar будет включать поиск второго уровня КАЖДОГО элемента DOM, у которого есть дочерние элементы, до того, как он достигнет третьего уровня , в этот момент у него все еще будет несколько элементов, на которые он смотрит, прежде чем найти #sidebar. При указании элементов таким способом поиск в ширину распознал бы #page и знал бы, что ему нужно только продолжить поиск в этом элементе, а не продолжать весь DOM.

Если случай 2 быстрее (#sidebar):

Если браузер ищет весь документ в том порядке, в котором он написан, а не обрабатывает DOM как дерево, то он будет выполнять один линейный поиск, а не три линейных поиска. На самом деле, даже в лучшем случае, когда он достаточно умен, чтобы распознавать начальную и конечную точки ранее найденного элемента DOM (по сути, поиск в глубину), ему все равно придется читать столько же строк кода в линейный поиск - сначала он будет читать, пока не найдет #page, затем он начнет читать с начала #page до тех пор, пока не найдет #center, затем он будет читать с начала #center, пока не найдет #sidebar. Единственная разница в этом случае заключается в небольшом количестве накладных расходов, связанных с переключением с одного поиска на другой

Ответы [ 4 ]

4 голосов
/ 24 января 2011

Короткая история: чем больше всего вы используете, тем медленнее он анализируется.

Идентификатор всегда уникален, поэтому вам следует использовать только один;но даже с классами указание любых других элементов или критериев всегда будет медленнее.

http://css -tricks.com /ffective-render-css /

Эта статья намного углубляется в то, о чем вы спрашиваете.

4 голосов
/ 24 января 2011

AFAIK, нет никакого способа проверить скорость алгоритма соответствия CSS браузеров, и различия между #page #central #sidebar и #sidebar с точки зрения скорости настолько незначительны, что о них не стоит беспокоиться.

Что стоит беспокоить, так это разница в специфичности .

Иногда стоит добавить дополнительный идентификатор / класс / элемент к селектору, чтобы убедиться, что стиль не будет перезаписан по ошибке простым селектором позже в каскаде.

#page #central #sidebar p имеет специфичность 3-0-1, в то время как #sidebar p имеет специфичность 1-0-1, что означает, что #page #central #sidebar p будет иметь приоритет.

Кроме того, вы упомянули:

... если #sidebar находится в #page #central, он всегда должен быть в #page #central. Не важно что. На каждой странице.

Это очень не так, и важно понять, почему. Тот факт, что id уникален, не означает, что он должен соответствовать точной одинаковой структуре страницы на каждой странице.

Например: популярная система управления контентом (Drupal) позволяет разработчику определять правила размещения блоков на разных участках разных страниц. Возможно, я хочу, чтобы #search-block находился в #header на домашней странице, а затем в #sidebar на всех других страницах. использование более специфичного селектора позволило бы мне задать #search-block различных стилей в зависимости от того, какие у него родительские контейнеры.

1 голос
/ 24 января 2011

Я не знаю о производительности, и мне все равно, но объединение нескольких селекторов идентификаторов, безусловно, означает не то же самое, что использование только одного селектора идентификаторов, и я почти уверен, что люди не связывают селекторы таким образом по причинам производительности чем что-либо еще.

#page #central #sidebar p

Это только находит p в #sidebar, если #sidebar находится в #central, который находится внутри #page. Поэтому не не найдет эти #sidebar с:

<body>
    <div id="sidebar"></div>
</body>

<body>
    <div id="page">
        <div id="sidebar"></div>
    </div>
</body>

<body>
    <div id="central">
        <div id="sidebar"></div>
    </div>
</body>

Опять же, не уверен насчет производительности, но, конечно, браузер должен выполнять больше работы, потому что он должен проверять иерархию DOM для каждого элемента, когда он анализирует этот селектор справа налево. Это по реальной причине; если ваш CSS говорит, что стиль #sidebar такой-то и такой-то, только если он найден в #page #central, браузер должен будет выполнить эти проверки, прежде чем пытаться применить стили.

#sidebar p

Это находит p в #sidebar, везде, где в DOM #sidebar может находиться.

Также, возможно, я неправильно понял ваш вопрос, но относительно этого:

Поскольку «боковая панель» является идентификатором, на всей странице должна быть только одна «боковая панель» (при условии, что она проверяет, что я и делаю, позаботилась об этом). Поэтому, если #sidebar находится в #page #central, оно должно всегда быть в #page #central. Не важно что. На каждой странице.

Нет, не всегда. Вы можете разместить #sidebar где угодно, просто селектор со всеми тремя идентификаторами поднимает #sidebar тогда и только тогда, когда находится в #page #central. Единственный способ удовлетворить ваше предположение - убедиться, что ваша разметка структурирована как таковая. Ваши стили не могут и не будут знать о вашей разметке, особенно если она используется для стилизации нескольких страниц на сайте.

С учетом вышесказанного, если вы можете убедиться, что ваша разметка всегда содержит #page #central #sidebar в этой структуре, тогда нет проблем с выбором только #sidebar. Я хочу сказать, что разные селекторы означают разные вещи, и вы не просто выбираете одно или другое из соображений производительности - чаще всего это не так.

1 голос
/ 24 января 2011

Помимо проблем с производительностью, это не всегда означает одно и то же .

#header {
   background: blue;
}

#home #header {
   background: red;
}

Это совершенно правильное использование каскада, чтобы одна страница отличалась от другой. Я использую этот шаблон все время, обычно потому, что я присваиваю class или id своему элементу body, как ловушку для CSS и JavaScript.

...