优化CSS选择符

        CSS选择符对性能的影响源于浏览器匹配选择符和文档元素时所消耗的时间,前端攻城狮们可以通过编写更高效的选择符来控制匹配耗时,实现高效率选择符首先要理解选择符是如何匹配的。

1 CSS匹配规则:最右边优先

           看下面这条规则:

 #toc > LI {
      font-weight:bold;
 }

对于我们大多数有从左到右阅读习惯的人,可能自然而然的认为浏览器也是执行从左到右的匹配规则,因此会认为这条规则的开销并不高。我们普遍认为浏览器会这样工作:找到唯一的id为toc的元素,然后继续寻找这个元素的直系子元素LI,把样式应用到LI上。我们知道只有一个id为toc的元素,并且它只有几个LI子元素,所以这个CSS选择符应该相当高效。然鹅,浏览器并没有按照我们的套路走,事实上,CSS选择符是按照从右到左的顺序进行匹配的。了解这个特性后,我们知道这个之前看似高效的规则实际上开销相当高,浏览器必须遍历页面上每个LI元素并确定其父元素的id是否为toc。后代选择符的效率更糟:

#toc  A{
     color:#fff;
}

在这个选择符中,浏览器会检查整个文档中的每个链接,然而,浏览器并不仅仅检查每个链接的父元素,甚至还要遍历文档树去查找id为toc的祖先元素。如果被检查的链接不是toc元素的后代,那么浏览器就要向上一级遍历直到文档的根节点。在看一个例子:

DIV DIV DIV P A.class0007{
    color:red;
}

一眼看上去,这似乎是一个开销很高的选择符,它是一个要匹配5级祖先元素的后代选择符,然而浏览器会从右到左进行匹配,所以这个后代选择符的速度和一个更简单的类选择符差不多。最右边的参数也叫关键选择符,它对浏览器执行的工作量起主要影响。在本例中,关键选择符是A.class0007,页面中只有一个元素匹配这个关键选择符,所以这个选择符的匹配时间是极少的。

           样式系统从最右边的选择符开始向左匹配规则。只要当前选择符的左边还有其它选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出。

2 编写高效的CSS选择符

           理解了选择符的右边优先原则,我们就可以从另一个角度看CSS选择符,并将其调整得更高效。下面是一些编写高效选择符的指南:

  • 避免使用通配规则

除了传统意义上的通配选择符之外,Hyatt也把相邻兄弟选择符、子选择符、后代选择符和属性选择符都归纳到“通配规则”分类下。他推荐仅使用ID、类和标签选择符。

  • 不要限定ID选择符

在页面中一个指定ID只能对应一个元素,所以没有必要添加额外的限定符。例如:

DIV#toc 是没有必要的,应该简化为#toc。

  • 不要限定类选择符

不要用具体的标签限定类选择符,而是根据实际情况对类型进行扩展。例如:

把LI.chapter 改成 .li-chapter。

  • 让规则越具体越好

不要试图编写像OL LI A这样的长选择符,最好是创建一个像.list-anchor一样的类,并把它添加到适当的元素上。

  • 避免使用后代选择符

处理后代选择符的开销是最高的,而通常使用子选择符也可以得到想要的结果,并且更高效。遵循下一条指南就更好了,这样连子选择符也可以避免使用了。

  • 避免使用标签—子选择符

如果有像#toc  > LI  > A 这样的基于标签的子选择符,那么应该使用一个类来关联每个标签元素,比如.toc-anchor。

  • 质疑子选择符的所有用途

再次提醒攻城狮们所有使用子选择符的地方,尽可能用具体的类取代它们。

  • 依靠继承

了解哪些属性可以通过继承而来,然后避免对这些属性重复指定规则。例如,对列表元素而不是每个列表项元素指定list-style-image.

3 认识回流时间

         上面的例子都是关于CSS选择符在加载匹配上的影响,对于CSS的性能,还有个问题需要我们考虑:当用户和页面进行交互时,浏览器应用样式和布局元素所消耗的时间,即回流时间。

         当使用JavaScript修改DOM元素样式的某些属性时会触发回流。例如修改一个元素的border、padding等等。回流并不需要涉及页面上的所有元素,仅仅对那些受回流影响的元素进行重新布局。如果修改了一个文档的body或其他一些有很多后代元素的padding属性,那么回流的开销就会相当高。

         回流需要重新应用CSS规则,浏览器必须再次匹配所有的CSS选择符。如果CSS选择符是低效的,回流可能消耗的时间就会多到引起用户的注意。因此,杜绝低效的CSS选择符的影响,不仅要考虑页面加载时间,也要考虑用户和网页交互时样式的表现。

猜你喜欢

转载自blog.csdn.net/u014399368/article/details/81232852
今日推荐