博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS选择器从右向左的匹配规则
阅读量:4116 次
发布时间:2019-05-25

本文共 1149 字,大约阅读时间需要 3 分钟。

640?wx_fmt=jpeg

作者 | 赵东禹

来源 | http://www.cnblogs.com/zhaodongyu/p/3341080.html

下面这个栗子,CSS选择器它是如何工作的?

 

.mod-nav h3 span {font-size: 16px;}

如果不知道匹配规则,可能的理解是从左向右匹配:先找到.mod-nav,然后逐级匹配h3、span,在这个过程中如果遍历到叶子节点都没有匹配就需要回溯,继续寻找下一个分支。

但事实上,CSS选择器的读取顺序是从右向左。

还是上面的选择器,它的读取顺序变成:先找到所有的span,沿着span的父元素查找h3,中途找到了符合匹配规则的节点就加入结果集;如果直到根元素html都没有匹配,则不再遍历这条路径,从下一个span开始重复这个过程(如果有多个最右节点为span的话)。

在某条CSS规则下(比如.mod-nav h3 span),会形成一条符合规则的索引树,树由上至下的节点是规则中从右向左的一个个选择符匹配的节点。索引树遍历的具体过程可以看寒冬大大的一段视频。

为什么从右向左的规则要比从左向右的高效?

640?wx_fmt=png

假如DOM的结构如上图,匹配规则是.mod-nav h3 span。

若从左向右的匹配,过程是:从.mod-nav开始,遍历子节点header和子节点div,然后各自向子节点遍历。

在右侧div的分支中,最后遍历到叶子节点a,发现不符合规则,需要回溯到ul节点,再遍历下一个li-a,假如有1000个li,则这1000次的遍历与回溯会损失很多性能。

再看看从右至左的匹配:先找到所有的最右节点span,对于每一个span,向上寻找节点h3,由h3再向上寻找class=mod-nav的节点,最后找到根元素html则结束这个分支的遍历。

很明显,两种匹配规则的性能差别很大。之所以会差别很大,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。

当然这是比较明显情况,如果在叶子上存在多个不符合条件的span,从右向左的规则也会走一些弯路(这时就需要优化CSS选择器了)。

但平均来说它还是更高效,因为大多时候,一个DOM树中,符合匹配条件的节点(如.mod-nav h3 span)远远远远少于不符合条件的节点。

jQuery从1.3版本开始使用的Sizzle引擎,它按照了CSS选择器的匹配规则(从右至左)进行DOM元素的查找与匹配(当然其中做了很多优化),性能得到了很大的提升。

最后,这边有个视频是@winter之前分享的《关于浏览器的背后》,有兴趣的童鞋也可以看下:http://v.youku.com/v_show/id_XMjMzMzU2NDc2.html

640?wx_fmt=jpeg

640?wx_fmt=png

你可能感兴趣的文章
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
PHP 7 的五大新特性
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
OpenCV meanshift目标跟踪总结
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
听说玩这些游戏能提升编程能力?
查看>>
如果你还不了解 RTC,那我强烈建议你看看这个!
查看>>
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
Mysql复制表以及复制数据库
查看>>
Linux系统编程——线程池
查看>>
Linux C++线程池实例
查看>>
shared_ptr的一些尴尬
查看>>
C++总结8——shared_ptr和weak_ptr智能指针
查看>>
c++写时拷贝1
查看>>
Linux网络编程---I/O复用模型之poll
查看>>
Java NIO详解
查看>>