div.name
比:
.name
但是我最近读过大多数CSS选择引擎从右到左读取,在这种情况下,第一个例子实际上不会更慢?由于选择器引擎会简单地找到一个名称类的每个元素,然后必须确定哪些元素是div?
CSS选择器引擎一般阅读哪种方式?从左到右还是从右到左?如果他们一般从右到左阅读,有人可以给我一个解释,为什么(我看不到从选择器引擎的右边读取是有意义的)?
解决方法
However I’ve read recently that most CSS selector engines read from right to left,in which case wouldn’t the first example actually be slower?
Which way to CSS selector engines read in general? Left to right or right to left? And if they generally read right to left could someone please offer me an explanation as to why (I can’t see how it makes sense to read right to left in terms of a selector engine)?
坦率地说,告诉哪个选择器在给定的浏览器中会更慢,这在浏览器中是不可能的.性能往往波动并且是不可预测的,特别是在这种微观尺度和不可预测的文档结构.即使我们谈论理论表现,最终取决于实施.
话虽如此,如Boris Zbarsky’s answer to this other question和Guffa’s answer to yours所示,一个典型的浏览器(目前是所有主要布局引擎都是这样)是一个元素,并评估所有候选选择器,以查看它们匹配的选项,而不是找到一组元素匹配给定的选择器.这是一个微妙但非常重要的区别.鲍里斯提供的技术说明不仅非常详尽,而且具有权威性(因为他在Gecko上工作,Firefox使用的引擎),所以我强烈建议您阅读它.
但是我以为我应该解决你的问题似乎是另一个问题:
As the selector engine would simply find every element with a class of name,and then have to identify which of those were
div
s?
以及Patrick McElhaney’s comment:
The linked question explains why selectors are read right-to-left in general,so
#foo ul.round.fancy li.current
is readli.current,ul.round.fancy,#foo
,but is it really read right-to-left within each element (.current,li,.fancy,.round,ul,#foo
)? Should it be?
我从来没有实现CSS,也没有看到其他浏览器如何实现CSS.我们从上面的答案中知道,浏览器使用从右到左的匹配来跨选择器中的组合器,例如>在这个例子中的组合器:
section > div.second > div.third
如果一个元素不是一个div.third,那么没有任何点检查它的父对象是一个div.second,其父对象是一个section.
但是,我不相信这个从右到左的顺序一直下降到简单的选择器级别.换句话说,我不相信浏览器对于由一系列复合选择器分开的从右到左的评估中的简单选择器序列(也称为复合选择器)的每个部分使用从右到左的评估.组合子.
例如,考虑这个设计和高度夸张的选择器:
div.name[data-foo="bar"]:nth-child(5):hover::after
现在,不能保证浏览器将按照以下顺序检查元素的这些条件:
>指针是否超过这个元素?
这个元素是它的父母的第五个孩子吗?
>该元素是否具有值bar的data-foo属性?
>这个元素是否有一个名称类?
这是一个div元素吗?
这个与上述功能完全相同的选择器,除了简单的选择器混乱之外,还必须按以下顺序进行评估:
div:hover[data-foo="bar"].name:nth-child(5)::after
这个元素是它的父母的第五个孩子吗?
>这个元素是否有一个名称类?
>该元素是否具有值bar的data-foo属性?
>指针是否超过这个元素?
这是一个div元素吗?
由于性能原因,这样的命令根本就没有理由执行.事实上,我会认为,通过选择某些类型的简单选择器,无论它们在哪个顺序中,性能都会得到提高. (你也会注意到:: after不算是 – 这是因为伪元素不是简单的选择器,从来没有输入匹配的方程式.)
例如,众所周知,ID选择器是最快的.那么鲍里斯在他对相关问题的回答的最后一段说:
Note also that there are other optimizations browsers already do to avoid even trying to match rules that definitely won’t match. For example,if the rightmost selector has an id and that id doesn’t match the element’s id,then there will be no attempt to match that selector against that element at all in Gecko: the set of “selectors with IDs” that are attempted comes from a hashtable lookup on the element’s ID. So this is 70% of the rules which have a pretty good chance of matching that still don’t match after considering just the tag/class/id of the rightmost selector.
换句话说,无论你有一个如下所示的选择器:
div#foo.bar:first-child
或这个:
div.bar:first-child#foo
Gecko将始终检查ID和类,无论它在顺序中位于何处.如果元素没有ID和与选择器匹配的类,那么它将被立即丢弃.如果你问我很快,
这只是Gecko的一个例子.这在实现之间也可能不同(例如,Gecko和WebKit可能与Trident甚至Presto不同).有些策略和方法通常由供应商商定,当然(首先检查ID不太可能有差异),但是细节可能会有所不同.