discuz的文档中有这么一句话:
勿使用冗余低效的 CSS 写法, 例如:ul li a span { ... }
http://faq.comsenz.com/librar...
不知道为什么这种写法会是冗余低效?
如果说直接使用标签选择器不好,那么改成这样呢:
ul.test li a span
关于选择器的层级问题,我不理解为什么超过三级会不好?
补充:
我作了个测试:
<div class="row">
<div class="haha">
<ul class="rul">
<li class="rli"><span class="ss" id="hi">你们好</span></li>
</ul>
</div>
</div>
<script>
//选择器性能测试
function test(fn){
var start=+new Date();
for(var i=0;i<1000000;i++){
fn();
}
var re=+new Date()-start;
console.log("用时:"+re);
}
function a(){
// $(jquery)--document.querySelector
//document.querySelector("div div ul li span"); //2349--505
//document.querySelector("div.row div ul li span"); //2292--515
//document.querySelector("div.row>div>ul>li>span"); //2340--535
//document.querySelector("div.row .haha .rul .rli .ss");//2273--535
//document.querySelector(".row .ss"); //2106--440
//document.querySelector(".ss"); //1096--120
//document.querySelector("span.ss"); //2060--350
//document.querySelector("#hi"); //535--116
//document.querySelector("span#hi"); //1895--150
}
test(a);
</script>
我作了上面的测试,结论是:
1.性能最优的选择器是:id与class ,id 略快一些,但页面中每多一个id就会在js中多一个全局变量,显然用id作选择器是不好的。
2.span#hi性能比#hi差,我看过一些文章说前者会更好,但从测试的结果来看并没有。
3.层级多的选择器,无论是用标签还是用class,性能都比较差。这点以下很多回答也都提到了,但我还是不太明白,这与我的直觉相矛盾。
按理说层级多,实际上缩小了查找的范围,不应该查找速度更快才对吗?
打个比喻:在某个区域的某个楼层的某个方向的某个房间里有个叫做"haha"的人,你要怎样才能更快地找到它?
是只告诉你它的名字,
还是告诉你它所在的区域,楼层,方向,房间号,再去查找会比较快?
另外,很多人提到关于代码的可维护性问题,我觉得这是因人而异的吧,我觉得添加一些id与class写起来更方便,多层级也更方便定位css的作用区域,更易于维护。
比如css中存在这两种代码:
A:
.content{}
.title{}
.p{}
.li{}
B:
.content{}
.content .title{}
.content p{}
.content p li{}
不是很明显B这种写法会更方便维护吗?而且可以更好地控制css代码的作用域,不是吗?
说一下规则匹配成功的过程,你试着模拟一遍:
浏览器解析到一个span element, 并且发现css规则里面有一个写着span的规则
ul li a span
,开始尝试是否匹配成功从span开始往父层上找,看看能否匹配到a (还不需要是直接父结点,只要链上有a就算,所以会一直往上匹配直到html或者浏览器剪枝发现已经不可能匹配为止)
找li(同上)
找ul(同上)
所以这个算法复杂度是指数级的
假设写到后面你的页面有大约2000个elements同时存在(SPA中型差不多就这个大小),大概有15层element嵌套,
第15层节点中有100个左右的span,那确定不能匹配a最多要14层查找,li 13层, ul 12层,再乘上span自己本身匹配的计算,这个页面交互基本就卡住了,就算不考虑交互的静态页面,这个运算量也是完全应该去避免的