为什么浏览器从右到左匹配CSSselect器?

浏览器引擎从右到左匹配CSSselect器。 所以他们首先find孩子,然后检查他们的父母,看他们是否符合规则的其余部分。

  1. 为什么是这样?
  2. 这只是因为规格说明吗?
  3. 如果从左到右进行评估,会影响最终的布局吗?

对我来说,最简单的方法就是使用元素数最less的select器。 所以ID首先(因为他们应该只返回1元素)。 然后可能是类或节点数最less的元素 – 例如,页面上可能只有一个跨度,因此可以使用任何引用跨度的规则直接到该节点。

以下是一些支持我的说法的链接

  1. http://code.google.com/speed/page-speed/docs/rendering.html
  2. https://developer.mozilla.org/en/Writing_Efficient_CSS

这听起来像是这样做的,以避免必须查看所有的父母的孩子(可能是很多),而不是所有的孩子的父母必须是一个。 即使DOM很深,它也只能在RTL匹配中查看每个级别的一个节点,而不是多个节点。 评估CSSselect器LTR或RTL更简单/更快吗?

请记住,当一个浏览器做select器匹配时,它有一个元素(试图确定样式的元素)和所有的规则以及它们的select器,它需要find哪个规则匹配元素。 这与通常的jQuery不同,比如说,只有一个select器,并且你需要find所有匹配该select器的元素。

如果只有一个select器,并且只有一个元素与该select器进行比较,则在某些情况下,从左到右更有意义。 但是,这决不是浏览器的情况。 浏览器正试图呈现Gmail或其他任何东西,并有一个<span>它试图风格和Gmail放入其样式表的10,000多条规则(我没有编号)。

尤其是在浏览器正在考虑大多数select器的情况下,它们与所讨论的元素匹配。 所以问题就变成了一个决定select器不能尽快匹配的问题。 如果这需要一些额外的工作,在匹配的情况下,你仍然赢得了所有的工作,你保存在不匹配的情况下。

如果您只是将select器的最右侧部分与您的元素进行匹配,那么机会就不会匹配,您就完成了。 如果它匹配,则必须做更多的工作,但只与树深度成比例,在大多数情况下这并不是那么大。

另一方面,如果你通过匹配select器的最左边部分开始,那么你与之匹配的是什么? 你必须开始走DOM,寻找可能匹配它的节点。 只要发现没有匹配,最左边的部分可能需要一段时间。

所以浏览器从右边看, 它给出了一个明显的起点,并且可以让你很快地摆脱大部分候选select器。 您可以在http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665上看到一些数据(虽然这个表示方式令人困惑),但结果却是,特别是Gmail两年前,对于(规则,元素)对的70%,您可以在检查规则的最右侧select器的标记/类/标识符部分后,判定规则不匹配。; Mozilla的页面载入性能testing套件的相应数字是72%。 因此,尽可能快地摆脱所有规则的2/3,然后只需要考虑匹配剩下的1/3。

还要注意的是,浏览器已经做了其他优化,以避免即使试图匹配绝对不匹配的规则。 例如,如果最右边的select器有一个id,并且该id与该元素的id不匹配,那么将不会尝试将该select器与Gecko中的该元素进行匹配:尝试的“具有ID的select器”集合来自元素ID的哈希表查找。 所以这是70%的规则,它们有相当好的匹配机会,在考虑最右边的select器的标签/类/ ID之后仍然不匹配。

它允许从更具体到不太具体的级联。 它也允许在应用中短路。 如果更具体的规则适用于父规则适用的所有方面,则将忽略所有父规则。 如果父项中有其他位,则应用它们。

如果你反过来,你会根据父母的格式,然后覆盖每次孩子有不同的东西。 从长远来看,这是比忽略已被照顾的规则中的项目更多的工作。

左右分析也被称为自底向上分析对浏览器来说实际上是有效的。

考虑以下几点:

 #menu ul li a { color: #00f; } 

浏览器首先检查a ,然后li ,然后ul ,然后#menu

这是因为当浏览器扫描页面时,只需要查看当前元素/节点以及它扫描的所有以前的节点/元素即可。

需要注意的是, 浏览器开始处理的时刻,它得到一个完整的标记/节点 ,不必等待整个页面,除非find一个脚本,在这种情况下,它暂时停顿,并完成脚本的执行,然后前进。

如果这样做的话,效率会很低,因为浏览器在第一次检查时发现它正在扫描的元素,但却被迫继续查看所有附加select器的文档。 为此浏览器需要有整个html,并可能需要扫描整个页面,然后开始css绘画。

这与大多数库parsingdom是相反的。 在那里构build了dom,它不需要扫描整个页面,只需find第一个元素,然后再匹配其中的其他元素。