Селекторы CSS сопоставляются движками браузера справа налево. Поэтому они сначала находят детей, а затем проверяют своих родителей, чтобы убедиться, что они соответствуют остальным частям правила.
- Почему это?
- Это только потому, что в спецификации сказано?
- Влияет ли это на возможный макет, если он был оценен слева направо?
Для меня самый простой способ сделать это - использовать селекторы с наименьшим количеством элементов. Сначала идентификаторы (так как они должны возвращать только 1 элемент). Тогда, возможно, классы или элемент, который имеет наименьшее количество узлов - например, на странице может быть только один промежуток, поэтому перейдите непосредственно к этому узлу с любым правилом, которое ссылается на промежуток.
Вот несколько ссылок, подтверждающих мои претензии
- http://code.google.com/speed/page-speed/docs/rendering.html
- https://developer.mozilla.org/en/Writing_Efficient_CSS
Похоже, что это сделано таким образом, чтобы не смотреть на всех детей родителя (которых может быть много), а не на всех родителей ребенка, который должен быть одним. Даже если DOM является глубоким, он будет рассматривать только один узел на уровень, а не несколько при сопоставлении RTL. Проще / быстрее оценить CSS селекторы LTR или RTL?
источник
#foo
селектор должен соответствовать всем этим узлам. У jQuery есть возможность сказать, что $ ("# foo") всегда будет возвращать только один элемент, потому что они определяют свой собственный API со своими правилами. Но браузеры должны реализовать CSS, и CSS говорит, что все в документе должно соответствовать заданному идентификатору.querySelectorAll
). В других случаях используется Sizzle. Sizzle не соответствует нескольким идентификаторам, но QSA соответствует (AYK). Выбор пути зависит от селектора, контекста, браузера и его версии. API запросов jQuery использует то, что я назвал «Native First, Dual Approach». Я написал статью об этом, но она не работает. Хотя вы можете найти здесь : avenbelow.ca/hosted/dhtmlkitchen/JavaScript-Query-Engines.htmlОтветы:
Имейте в виду, что когда браузер выполняет сопоставление селектора, у него есть один элемент (тот, для которого он пытается определить стиль) и все ваши правила и их селекторы, и ему нужно найти, какие правила соответствуют элементу. Это отличается от обычной вещи jQuery, скажем, когда у вас есть только один селектор, и вам нужно найти все элементы, которые соответствуют этому селектору.
Если у вас был только один селектор и только один элемент для сравнения с этим селектором, то слева направо имеет больше смысла в некоторых случаях. Но это определенно не ситуация браузера. Браузер пытается отобразить Gmail или что-то еще, и у него есть тот, который
<span>
он пытается стилизовать, и более 10000 правил, которые Gmail вставляет в свою таблицу стилей (я не придумываю это число).В частности, в ситуации, когда браузер просматривает большинство селекторов, которые он считает , не соответствуют рассматриваемому элементу. Таким образом, проблема состоит в том, чтобы решить, что селектор не соответствует так быстро, как это возможно; если это требует дополнительной работы в соответствующих случаях, вы все равно выигрываете из-за всей работы, которую вы сохраняете в случаях, которые не совпадают.
Если вы начнете с простого сопоставления самой правой части селектора с вашим элементом, скорее всего, он не будет совпадать, и все готово. Если он совпадает, вам придется выполнять больше работы, но только пропорционально глубине вашего дерева, которая в большинстве случаев не так велика.
С другой стороны, если вы начнете с сопоставления самой левой части селектора ... с чем вы сравниваете его? Вы должны начать ходить по DOM, ища узлы, которые могут ему соответствовать. Просто обнаружение, что ничто не соответствует этой самой левой части, может занять некоторое время.
Так что браузеры совпадают справа; это дает очевидную отправную точку и позволяет очень быстро избавиться от большинства кандидатов на выбор. Вы можете увидеть некоторые данные по адресу http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (хотя это вводит в заблуждение), но в результате Gmail в частности два года назад для 70% пар (правило, элемент) вы могли решить, что правило не совпадает, просто изучив части тега / класса / id самого правого селектора для правила. Соответствующий показатель для набора тестов производительности загрузки страниц Mozilla составил 72%. Так что действительно стоит попытаться избавиться от этих 2/3 всех правил так быстро, как вы можете, а затем беспокоиться только о соответствии оставшихся 1/3.
Также обратите внимание, что браузеры уже делают другие оптимизации, чтобы не пытаться даже соответствовать правилам, которые определенно не будут соответствовать. Например, если у крайнего правого селектора есть идентификатор, и этот идентификатор не совпадает с идентификатором элемента, то в Gecko не будет попытки сопоставить этот селектор с этим элементом вообще: набор «селекторов с идентификаторами», которые предпринимаются исходит из поиска по хеш-таблице идентификатора элемента. Так что это 70% правил, которые имеют довольно хорошие шансы на совпадение, которые все еще не совпадают после рассмотрения только тега / класса / id самого правого селектора.
источник
Разбор справа налево, также называемый анализом снизу вверх, на самом деле эффективен для браузера.
Учтите следующее:
Браузер сначала проверяет
a
, затемli
, потомul
и потом#menu
.Это потому, что браузер сканирует страницу, ему просто нужно посмотреть текущий элемент / узел и все предыдущие узлы / элементы, которые он сканировал.
Следует отметить, что браузер начинает обработку в тот момент, когда он получает полный тег / узел, и ему не нужно ждать всю страницу, кроме случаев, когда он находит скрипт, и в этом случае он временно приостанавливает и завершает выполнение скрипта, а затем идет вперед.
Если это происходит наоборот, это будет неэффективно, потому что браузер обнаружил элемент, который он сканировал при первой проверке, но затем был вынужден продолжить просмотр документа для всех дополнительных селекторов. Для этого браузер должен иметь весь HTML и, возможно, должен сканировать всю страницу, прежде чем он начнет рисовать CSS.
Это противоречит тому, как большинство парсов разбирает дом. Там дом построен, и ему не нужно сканировать всю страницу, просто найдите первый элемент и затем продолжайте сопоставлять другие внутри него.
источник
Это позволяет каскадно переходить от более конкретного к менее конкретному. Это также допускает короткое замыкание в приложении. Если более конкретное правило применяется во всех аспектах, к которым применяется родительское правило, все родительские правила игнорируются. Если в родительском элементе есть другие биты, они применяются.
Если бы вы пошли другим путем, вы должны отформатировать в соответствии с родителями, а затем перезаписывать каждый раз, когда у ребенка что-то другое. В конечном счете, это намного больше работы, чем игнорирование элементов в правилах, о которых уже позаботились.
источник